xref: /openbmc/linux/fs/ntfs/time.h (revision bcf451ec)
11da177e4SLinus Torvalds /*
21da177e4SLinus Torvalds  * time.h - NTFS time conversion functions.  Part of the Linux-NTFS project.
31da177e4SLinus Torvalds  *
4d8ec785eSAnton Altaparmakov  * Copyright (c) 2001-2005 Anton Altaparmakov
51da177e4SLinus Torvalds  *
61da177e4SLinus Torvalds  * This program/include file is free software; you can redistribute it and/or
71da177e4SLinus Torvalds  * modify it under the terms of the GNU General Public License as published
81da177e4SLinus Torvalds  * by the Free Software Foundation; either version 2 of the License, or
91da177e4SLinus Torvalds  * (at your option) any later version.
101da177e4SLinus Torvalds  *
111da177e4SLinus Torvalds  * This program/include file is distributed in the hope that it will be
121da177e4SLinus Torvalds  * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
131da177e4SLinus Torvalds  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
141da177e4SLinus Torvalds  * GNU General Public License for more details.
151da177e4SLinus Torvalds  *
161da177e4SLinus Torvalds  * You should have received a copy of the GNU General Public License
171da177e4SLinus Torvalds  * along with this program (in the main directory of the Linux-NTFS
181da177e4SLinus Torvalds  * distribution in the file COPYING); if not, write to the Free Software
191da177e4SLinus Torvalds  * Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
201da177e4SLinus Torvalds  */
211da177e4SLinus Torvalds 
221da177e4SLinus Torvalds #ifndef _LINUX_NTFS_TIME_H
231da177e4SLinus Torvalds #define _LINUX_NTFS_TIME_H
241da177e4SLinus Torvalds 
251da177e4SLinus Torvalds #include <linux/time.h>		/* For current_kernel_time(). */
261da177e4SLinus Torvalds #include <asm/div64.h>		/* For do_div(). */
271da177e4SLinus Torvalds 
281da177e4SLinus Torvalds #include "endian.h"
291da177e4SLinus Torvalds 
301da177e4SLinus Torvalds #define NTFS_TIME_OFFSET ((s64)(369 * 365 + 89) * 24 * 3600 * 10000000)
311da177e4SLinus Torvalds 
321da177e4SLinus Torvalds /**
331da177e4SLinus Torvalds  * utc2ntfs - convert Linux UTC time to NTFS time
341da177e4SLinus Torvalds  * @ts:		Linux UTC time to convert to NTFS time
351da177e4SLinus Torvalds  *
361da177e4SLinus Torvalds  * Convert the Linux UTC time @ts to its corresponding NTFS time and return
371da177e4SLinus Torvalds  * that in little endian format.
381da177e4SLinus Torvalds  *
39bcf451ecSArnd Bergmann  * Linux stores time in a struct timespec64 consisting of a time64_t tv_sec
40bcf451ecSArnd Bergmann  * and a long tv_nsec where tv_sec is the number of 1-second intervals since
41bcf451ecSArnd Bergmann  * 1st January 1970, 00:00:00 UTC and tv_nsec is the number of 1-nano-second
42bcf451ecSArnd Bergmann  * intervals since the value of tv_sec.
431da177e4SLinus Torvalds  *
441da177e4SLinus Torvalds  * NTFS uses Microsoft's standard time format which is stored in a s64 and is
451da177e4SLinus Torvalds  * measured as the number of 100-nano-second intervals since 1st January 1601,
461da177e4SLinus Torvalds  * 00:00:00 UTC.
471da177e4SLinus Torvalds  */
48bcf451ecSArnd Bergmann static inline sle64 utc2ntfs(const struct timespec64 ts)
491da177e4SLinus Torvalds {
501da177e4SLinus Torvalds 	/*
511da177e4SLinus Torvalds 	 * Convert the seconds to 100ns intervals, add the nano-seconds
521da177e4SLinus Torvalds 	 * converted to 100ns intervals, and then add the NTFS time offset.
531da177e4SLinus Torvalds 	 */
541da177e4SLinus Torvalds 	return cpu_to_sle64((s64)ts.tv_sec * 10000000 + ts.tv_nsec / 100 +
551da177e4SLinus Torvalds 			NTFS_TIME_OFFSET);
561da177e4SLinus Torvalds }
571da177e4SLinus Torvalds 
581da177e4SLinus Torvalds /**
591da177e4SLinus Torvalds  * get_current_ntfs_time - get the current time in little endian NTFS format
601da177e4SLinus Torvalds  *
611da177e4SLinus Torvalds  * Get the current time from the Linux kernel, convert it to its corresponding
621da177e4SLinus Torvalds  * NTFS time and return that in little endian format.
631da177e4SLinus Torvalds  */
641da177e4SLinus Torvalds static inline sle64 get_current_ntfs_time(void)
651da177e4SLinus Torvalds {
66bcf451ecSArnd Bergmann 	struct timespec64 ts;
67bcf451ecSArnd Bergmann 
68bcf451ecSArnd Bergmann 	ktime_get_coarse_real_ts64(&ts);
69bcf451ecSArnd Bergmann 	return utc2ntfs(ts);
701da177e4SLinus Torvalds }
711da177e4SLinus Torvalds 
721da177e4SLinus Torvalds /**
731da177e4SLinus Torvalds  * ntfs2utc - convert NTFS time to Linux time
741da177e4SLinus Torvalds  * @time:	NTFS time (little endian) to convert to Linux UTC
751da177e4SLinus Torvalds  *
761da177e4SLinus Torvalds  * Convert the little endian NTFS time @time to its corresponding Linux UTC
771da177e4SLinus Torvalds  * time and return that in cpu format.
781da177e4SLinus Torvalds  *
79bcf451ecSArnd Bergmann  * Linux stores time in a struct timespec64 consisting of a time64_t tv_sec
80bcf451ecSArnd Bergmann  * and a long tv_nsec where tv_sec is the number of 1-second intervals since
81bcf451ecSArnd Bergmann  * 1st January 1970, 00:00:00 UTC and tv_nsec is the number of 1-nano-second
82bcf451ecSArnd Bergmann  * intervals since the value of tv_sec.
831da177e4SLinus Torvalds  *
841da177e4SLinus Torvalds  * NTFS uses Microsoft's standard time format which is stored in a s64 and is
851da177e4SLinus Torvalds  * measured as the number of 100 nano-second intervals since 1st January 1601,
861da177e4SLinus Torvalds  * 00:00:00 UTC.
871da177e4SLinus Torvalds  */
88bcf451ecSArnd Bergmann static inline struct timespec64 ntfs2utc(const sle64 time)
891da177e4SLinus Torvalds {
90bcf451ecSArnd Bergmann 	struct timespec64 ts;
911da177e4SLinus Torvalds 
921da177e4SLinus Torvalds 	/* Subtract the NTFS time offset. */
93d8ec785eSAnton Altaparmakov 	u64 t = (u64)(sle64_to_cpu(time) - NTFS_TIME_OFFSET);
941da177e4SLinus Torvalds 	/*
951da177e4SLinus Torvalds 	 * Convert the time to 1-second intervals and the remainder to
961da177e4SLinus Torvalds 	 * 1-nano-second intervals.
971da177e4SLinus Torvalds 	 */
981da177e4SLinus Torvalds 	ts.tv_nsec = do_div(t, 10000000) * 100;
991da177e4SLinus Torvalds 	ts.tv_sec = t;
1001da177e4SLinus Torvalds 	return ts;
1011da177e4SLinus Torvalds }
1021da177e4SLinus Torvalds 
1031da177e4SLinus Torvalds #endif /* _LINUX_NTFS_TIME_H */
104