1 /* datetime.c - Module for common datetime function. */
3 * GRUB -- GRand Unified Bootloader
4 * Copyright (C) 2008 Free Software Foundation, Inc.
6 * GRUB is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * GRUB is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
20 #include <grub/datetime.h>
21 #include <grub/i18n.h>
23 static const char *const grub_weekday_names
[] =
35 grub_get_weekday (struct grub_datetime
*datetime
)
39 if (datetime
->month
<= 2)
43 y
= datetime
->year
- a
;
44 m
= datetime
->month
+ 12 * a
- 2;
46 return (datetime
->day
+ y
+ y
/ 4 - y
/ 100 + y
/ 400 + (31 * m
/ 12)) % 7;
50 grub_get_weekday_name (struct grub_datetime
*datetime
)
52 return _ (grub_weekday_names
[grub_get_weekday (datetime
)]);
56 #define SECPERHOUR (60*SECPERMIN)
57 #define SECPERDAY (24*SECPERHOUR)
58 #define DAYSPERYEAR 365
59 #define DAYSPER4YEARS (4*DAYSPERYEAR+1)
63 grub_unixtime2datetime (grub_int32_t nix
, struct grub_datetime
*datetime
)
66 grub_uint8_t months
[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
67 /* In the period of validity of unixtime all years divisible by 4
69 /* Convenience: let's have 3 consecutive non-bissextile years
70 at the beginning of the counting date. So count from 1901. */
72 /* Number of days since 1st Januar, 1901. */
74 /* Seconds into current day. */
76 /* Transform C divisions and modulos to mathematical ones */
78 days_epoch
= -(((unsigned) (SECPERDAY
-nix
-1)) / SECPERDAY
);
80 days_epoch
= ((unsigned) nix
) / SECPERDAY
;
81 secs_in_day
= nix
- days_epoch
* SECPERDAY
;
82 days
= days_epoch
+ 69 * DAYSPERYEAR
+ 17;
84 datetime
->year
= 1901 + 4 * (days
/ DAYSPER4YEARS
);
85 days
%= DAYSPER4YEARS
;
86 /* On 31st December of bissextile years 365 days from the beginning
87 of the year elapsed but year isn't finished yet */
88 if (days
/ DAYSPERYEAR
== 4)
91 days
-= 3*DAYSPERYEAR
;
95 datetime
->year
+= days
/ DAYSPERYEAR
;
99 && days
>= (i
==1 && datetime
->year
% 4 == 0
100 ? 29 : months
[i
]); i
++)
101 days
-= (i
==1 && datetime
->year
% 4 == 0
103 datetime
->month
= i
+ 1;
104 datetime
->day
= 1 + days
;
105 datetime
->hour
= (secs_in_day
/ SECPERHOUR
);
106 secs_in_day
%= SECPERHOUR
;
107 datetime
->minute
= secs_in_day
/ SECPERMIN
;
108 datetime
->second
= secs_in_day
% SECPERMIN
;