/src/serenity/AK/DOSPackedTime.cpp
Line | Count | Source |
1 | | /* |
2 | | * Copyright (c) 2022, Undefine <undefine@undefine.pl> |
3 | | * |
4 | | * SPDX-License-Identifier: BSD-2-Clause |
5 | | */ |
6 | | |
7 | | #include <AK/DOSPackedTime.h> |
8 | | #include <AK/Error.h> |
9 | | |
10 | | namespace AK { |
11 | | |
12 | | constexpr auto seconds_per_day = 86'400; |
13 | | |
14 | | UnixDateTime time_from_packed_dos(DOSPackedDate date, DOSPackedTime time) |
15 | 0 | { |
16 | 0 | if (date.value == 0) |
17 | 0 | return UnixDateTime::from_unix_time_parts(first_dos_year, 1, 1, 0, 0, 0, 0); |
18 | | |
19 | 0 | return UnixDateTime::from_unix_time_parts(first_dos_year + date.year, date.month, date.day, time.hour, time.minute, time.second * 2, 0); |
20 | 0 | } |
21 | | |
22 | | DOSPackedDate to_packed_dos_date(unsigned year, unsigned month, unsigned day) |
23 | 0 | { |
24 | 0 | DOSPackedDate date; |
25 | 0 | date.year = year - first_dos_year; |
26 | 0 | date.month = month; |
27 | 0 | date.day = day; |
28 | |
|
29 | 0 | return date; |
30 | 0 | } |
31 | | |
32 | | DOSPackedTime to_packed_dos_time(unsigned hour, unsigned minute, unsigned second) |
33 | 0 | { |
34 | 0 | DOSPackedTime time; |
35 | 0 | time.hour = hour; |
36 | 0 | time.minute = minute; |
37 | 0 | time.second = second / 2; |
38 | |
|
39 | 0 | return time; |
40 | 0 | } |
41 | | |
42 | | ErrorOr<DOSPackedDate> to_packed_dos_date(UnixDateTime const& unix_date_time) |
43 | 0 | { |
44 | 0 | auto truncated_seconds_since_epoch = unix_date_time.truncated_seconds_since_epoch(); |
45 | 0 | if (truncated_seconds_since_epoch < first_dos_representable_unix_timestamp || truncated_seconds_since_epoch > static_cast<i64>(last_dos_representable_unix_timestamp)) |
46 | 0 | return EINVAL; |
47 | | |
48 | 0 | u64 days_since_epoch = truncated_seconds_since_epoch / seconds_per_day; |
49 | |
|
50 | 0 | auto [year, month, day] = days_since_epoch_to_date(days_since_epoch); |
51 | |
|
52 | 0 | return to_packed_dos_date(year, month, day); |
53 | 0 | } |
54 | | |
55 | | ErrorOr<DOSPackedTime> to_packed_dos_time(UnixDateTime const& unix_date_time) |
56 | 0 | { |
57 | 0 | constexpr auto seconds_per_hour = 3'600; |
58 | 0 | constexpr auto seconds_per_minute = 60; |
59 | |
|
60 | 0 | auto date = TRY(to_packed_dos_date(unix_date_time)); |
61 | |
|
62 | 0 | auto truncated_seconds_since_epoch = unix_date_time.truncated_seconds_since_epoch(); |
63 | 0 | auto leftover_seconds = truncated_seconds_since_epoch - days_since_epoch(date.year + first_dos_year, date.month, date.day) * seconds_per_day; |
64 | |
|
65 | 0 | auto hours = leftover_seconds / seconds_per_hour; |
66 | 0 | leftover_seconds -= hours * seconds_per_hour; |
67 | |
|
68 | 0 | auto minutes = leftover_seconds / seconds_per_minute; |
69 | 0 | leftover_seconds -= minutes * seconds_per_minute; |
70 | |
|
71 | 0 | return to_packed_dos_time(hours, minutes, leftover_seconds); |
72 | 0 | } |
73 | | |
74 | | } |