summaryrefslogtreecommitdiff
path: root/include/ntfs-3g/ntfstime.h (plain)
blob: 2225d39d636bfde5fbcb950dbde67a90f65f4c8e
1/*
2 * ntfstime.h - NTFS time related functions. Originated from the Linux-NTFS project.
3 *
4 * Copyright (c) 2005 Anton Altaparmakov
5 * Copyright (c) 2005 Yura Pakhuchiy
6 * Copyright (c) 2010 Jean-Pierre Andre
7 *
8 * This program/include file is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as published
10 * by the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program/include file is distributed in the hope that it will be
14 * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
15 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program (in the main directory of the NTFS-3G
20 * distribution in the file COPYING); if not, write to the Free Software
21 * Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 */
23
24#ifndef _NTFS_NTFSTIME_H
25#define _NTFS_NTFSTIME_H
26
27#ifdef HAVE_TIME_H
28#include <time.h>
29#endif
30#ifdef HAVE_SYS_STAT_H
31#include <sys/stat.h>
32#endif
33#ifdef HAVE_GETTIMEOFDAY
34#include <sys/time.h>
35#endif
36
37#include "types.h"
38
39/*
40 * assume "struct timespec" is not defined if st_mtime is not defined
41 */
42#if !defined(st_mtime) & !defined(__timespec_defined)
43/*struct timespec {
44 time_t tv_sec;
45 long tv_nsec;
46} */;
47#endif
48
49/*
50 * There are four times more conversions of internal representation
51 * to ntfs representation than any other conversion, so the most
52 * efficient internal representation is ntfs representation
53 * (with low endianness)
54 */
55typedef sle64 ntfs_time;
56
57#define NTFS_TIME_OFFSET ((s64)(369 * 365 + 89) * 24 * 3600 * 10000000)
58
59/**
60 * ntfs2timespec - Convert an NTFS time to Unix time
61 * @ntfs_time: An NTFS time in 100ns units since 1601
62 *
63 * NTFS stores times as the number of 100ns intervals since January 1st 1601 at
64 * 00:00 UTC. This system will not suffer from Y2K problems until ~57000AD.
65 *
66 * Return: A Unix time (number of seconds since 1970, and nanoseconds)
67 */
68static __inline__ struct timespec ntfs2timespec(ntfs_time ntfstime)
69{
70 struct timespec spec;
71 s64 cputime;
72
73 cputime = sle64_to_cpu(ntfstime);
74 spec.tv_sec = (cputime - (NTFS_TIME_OFFSET)) / 10000000;
75 spec.tv_nsec = (cputime - (NTFS_TIME_OFFSET)
76 - (s64)spec.tv_sec*10000000)*100;
77 /* force zero nsec for overflowing dates */
78 if ((spec.tv_nsec < 0) || (spec.tv_nsec > 999999999))
79 spec.tv_nsec = 0;
80 return (spec);
81}
82
83/**
84 * timespec2ntfs - Convert Linux time to NTFS time
85 * @utc_time: Linux time to convert to NTFS
86 *
87 * Convert the Linux time @utc_time to its corresponding NTFS time.
88 *
89 * Linux stores time in a long at present and measures it as the number of
90 * 1-second intervals since 1st January 1970, 00:00:00 UTC
91 * with a separated non-negative nanosecond value
92 *
93 * NTFS uses Microsoft's standard time format which is stored in a sle64 and is
94 * measured as the number of 100 nano-second intervals since 1st January 1601,
95 * 00:00:00 UTC.
96 *
97 * Return: An NTFS time (100ns units since Jan 1601)
98 */
99static __inline__ ntfs_time timespec2ntfs(struct timespec spec)
100{
101 s64 units;
102
103 units = (s64)spec.tv_sec * 10000000
104 + NTFS_TIME_OFFSET + spec.tv_nsec/100;
105 return (cpu_to_le64(units));
106}
107
108/*
109 * Return the current time in ntfs format
110 */
111
112static __inline__ ntfs_time ntfs_current_time(void)
113{
114 struct timespec now;
115
116#if defined(HAVE_CLOCK_GETTIME) || defined(HAVE_SYS_CLOCK_GETTIME)
117 clock_gettime(CLOCK_REALTIME, &now);
118#elif defined(HAVE_GETTIMEOFDAY)
119 struct timeval microseconds;
120
121 gettimeofday(&microseconds, (struct timezone*)NULL);
122 now.tv_sec = microseconds.tv_sec;
123 now.tv_nsec = microseconds.tv_usec*1000;
124#else
125 now.tv_sec = time((time_t*)NULL);
126 now.tv_nsec = 0;
127#endif
128 return (timespec2ntfs(now));
129}
130
131#endif /* _NTFS_NTFSTIME_H */
132