Linux Kernel
3.7.1
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
fs
udf
udftime.c
Go to the documentation of this file.
1
/* Copyright (C) 1993, 1994, 1995, 1996, 1997 Free Software Foundation, Inc.
2
This file is part of the GNU C Library.
3
Contributed by Paul Eggert (
[email protected]
).
4
5
The GNU C Library is free software; you can redistribute it and/or
6
modify it under the terms of the GNU Library General Public License as
7
published by the Free Software Foundation; either version 2 of the
8
License, or (at your option) any later version.
9
10
The GNU C Library is distributed in the hope that it will be useful,
11
but WITHOUT ANY WARRANTY; without even the implied warranty of
12
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
Library General Public License for more details.
14
15
You should have received a copy of the GNU Library General Public
16
License along with the GNU C Library; see the file COPYING.LIB. If not,
17
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18
Boston, MA 02111-1307, USA. */
19
20
/*
21
* dgb 10/02/98: ripped this from glibc source to help convert timestamps
22
* to unix time
23
* 10/04/98: added new table-based lookup after seeing how ugly
24
* the gnu code is
25
* blf 09/27/99: ripped out all the old code and inserted new table from
26
* John Brockmeyer (without leap second corrections)
27
* rewrote udf_stamp_to_time and fixed timezone accounting in
28
* udf_time_to_stamp.
29
*/
30
31
/*
32
* We don't take into account leap seconds. This may be correct or incorrect.
33
* For more NIST information (especially dealing with leap seconds), see:
34
* http://www.boulder.nist.gov/timefreq/pubs/bulletin/leapsecond.htm
35
*/
36
37
#include "
udfdecl.h
"
38
39
#include <linux/types.h>
40
#include <linux/kernel.h>
41
42
#define EPOCH_YEAR 1970
43
44
#ifndef __isleap
45
/* Nonzero if YEAR is a leap year (every 4 years,
46
except every 100th isn't, and every 400th is). */
47
#define __isleap(year) \
48
((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0))
49
#endif
50
51
/* How many days come before each month (0-12). */
52
static
const
unsigned
short
int
__mon_yday[2][13] = {
53
/* Normal years. */
54
{0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365},
55
/* Leap years. */
56
{0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366}
57
};
58
59
#define MAX_YEAR_SECONDS 69
60
#define SPD 0x15180
/*3600*24 */
61
#define SPY(y, l, s) (SPD * (365 * y + l) + s)
62
63
static
time_t
year_seconds[
MAX_YEAR_SECONDS
] = {
64
/*1970*/
SPY
(0, 0, 0),
SPY
(1, 0, 0),
SPY
(2, 0, 0),
SPY
(3, 1, 0),
65
/*1974*/
SPY
(4, 1, 0),
SPY
(5, 1, 0),
SPY
(6, 1, 0),
SPY
(7, 2, 0),
66
/*1978*/
SPY
(8, 2, 0),
SPY
(9, 2, 0),
SPY
(10, 2, 0),
SPY
(11, 3, 0),
67
/*1982*/
SPY
(12, 3, 0),
SPY
(13, 3, 0),
SPY
(14, 3, 0),
SPY
(15, 4, 0),
68
/*1986*/
SPY
(16, 4, 0),
SPY
(17, 4, 0),
SPY
(18, 4, 0),
SPY
(19, 5, 0),
69
/*1990*/
SPY
(20, 5, 0),
SPY
(21, 5, 0),
SPY
(22, 5, 0),
SPY
(23, 6, 0),
70
/*1994*/
SPY
(24, 6, 0),
SPY
(25, 6, 0),
SPY
(26, 6, 0),
SPY
(27, 7, 0),
71
/*1998*/
SPY
(28, 7, 0),
SPY
(29, 7, 0),
SPY
(30, 7, 0),
SPY
(31, 8, 0),
72
/*2002*/
SPY
(32, 8, 0),
SPY
(33, 8, 0),
SPY
(34, 8, 0),
SPY
(35, 9, 0),
73
/*2006*/
SPY
(36, 9, 0),
SPY
(37, 9, 0),
SPY
(38, 9, 0),
SPY
(39, 10, 0),
74
/*2010*/
SPY
(40, 10, 0),
SPY
(41, 10, 0),
SPY
(42, 10, 0),
SPY
(43, 11, 0),
75
/*2014*/
SPY
(44, 11, 0),
SPY
(45, 11, 0),
SPY
(46, 11, 0),
SPY
(47, 12, 0),
76
/*2018*/
SPY
(48, 12, 0),
SPY
(49, 12, 0),
SPY
(50, 12, 0),
SPY
(51, 13, 0),
77
/*2022*/
SPY
(52, 13, 0),
SPY
(53, 13, 0),
SPY
(54, 13, 0),
SPY
(55, 14, 0),
78
/*2026*/
SPY
(56, 14, 0),
SPY
(57, 14, 0),
SPY
(58, 14, 0),
SPY
(59, 15, 0),
79
/*2030*/
SPY
(60, 15, 0),
SPY
(61, 15, 0),
SPY
(62, 15, 0),
SPY
(63, 16, 0),
80
/*2034*/
SPY
(64, 16, 0),
SPY
(65, 16, 0),
SPY
(66, 16, 0),
SPY
(67, 17, 0),
81
/*2038*/
SPY
(68, 17, 0)
82
};
83
84
extern
struct
timezone
sys_tz
;
85
86
#define SECS_PER_HOUR (60 * 60)
87
#define SECS_PER_DAY (SECS_PER_HOUR * 24)
88
89
struct
timespec
*
90
udf_disk_stamp_to_time
(
struct
timespec
*
dest
,
struct
timestamp
src
)
91
{
92
int
yday;
93
u16
typeAndTimezone
=
le16_to_cpu
(src.
typeAndTimezone
);
94
u16
year
=
le16_to_cpu
(src.
year
);
95
uint8_t
type
= typeAndTimezone >> 12;
96
int16_t
offset
;
97
98
if
(type == 1) {
99
offset = typeAndTimezone << 4;
100
/* sign extent offset */
101
offset = (offset >> 4);
102
if
(offset == -2047)
/* unspecified offset */
103
offset = 0;
104
}
else
105
offset = 0;
106
107
if
((year <
EPOCH_YEAR
) ||
108
(year >=
EPOCH_YEAR
+
MAX_YEAR_SECONDS
)) {
109
return
NULL
;
110
}
111
dest->
tv_sec
= year_seconds[year -
EPOCH_YEAR
];
112
dest->
tv_sec
-= offset * 60;
113
114
yday = ((__mon_yday[
__isleap
(year)][src.
month
- 1]) + src.
day
- 1);
115
dest->
tv_sec
+= (((yday * 24) + src.
hour
) * 60 + src.
minute
) * 60 + src.
second
;
116
dest->
tv_nsec
= 1000 * (src.
centiseconds
* 10000 +
117
src.
hundredsOfMicroseconds
* 100 + src.
microseconds
);
118
return
dest
;
119
}
120
121
struct
timestamp
*
122
udf_time_to_disk_stamp
(
struct
timestamp
*
dest
,
struct
timespec
ts
)
123
{
124
long
int
days, rem,
y
;
125
const
unsigned
short
int
*
ip
;
126
int16_t
offset
;
127
128
offset = -
sys_tz
.tz_minuteswest;
129
130
if
(!dest)
131
return
NULL
;
132
133
dest->
typeAndTimezone
=
cpu_to_le16
(0x1000 | (offset & 0x0FFF));
134
135
ts.
tv_sec
+= offset * 60;
136
days = ts.
tv_sec
/
SECS_PER_DAY
;
137
rem = ts.
tv_sec
%
SECS_PER_DAY
;
138
dest->
hour
= rem /
SECS_PER_HOUR
;
139
rem %=
SECS_PER_HOUR
;
140
dest->
minute
= rem / 60;
141
dest->
second
= rem % 60;
142
y = 1970;
143
144
#define DIV(a, b) ((a) / (b) - ((a) % (b) < 0))
145
#define LEAPS_THRU_END_OF(y) (DIV (y, 4) - DIV (y, 100) + DIV (y, 400))
146
147
while
(days < 0 || days >= (
__isleap
(y) ? 366 : 365)) {
148
long
int
yg = y + days / 365 - (days % 365 < 0);
149
150
/* Adjust DAYS and Y to match the guessed year. */
151
days -= ((yg -
y
) * 365
152
+
LEAPS_THRU_END_OF
(yg - 1)
153
-
LEAPS_THRU_END_OF
(y - 1));
154
y = yg;
155
}
156
dest->
year
=
cpu_to_le16
(y);
157
ip = __mon_yday[
__isleap
(y)];
158
for
(y = 11; days < (
long
int
)ip[y]; --
y
)
159
continue
;
160
days -= ip[
y
];
161
dest->
month
= y + 1;
162
dest->
day
= days + 1;
163
164
dest->
centiseconds
= ts.
tv_nsec
/ 10000000;
165
dest->
hundredsOfMicroseconds
= (ts.
tv_nsec
/ 1000 -
166
dest->
centiseconds
* 10000) / 100;
167
dest->
microseconds
= (ts.
tv_nsec
/ 1000 - dest->
centiseconds
* 10000 -
168
dest->
hundredsOfMicroseconds
* 100);
169
return
dest
;
170
}
171
172
/* EOF */
Generated on Thu Jan 10 2013 14:50:12 for Linux Kernel by
1.8.2