156 行
4.4 KiB
Zig
156 行
4.4 KiB
Zig
const std = @import("std");
|
||
const testing = std.testing;
|
||
|
||
const DateTime = struct {
|
||
year: u64,
|
||
month: u64,
|
||
day: u64,
|
||
hour: u64,
|
||
minute: u64,
|
||
second: u64,
|
||
};
|
||
|
||
fn getDaysInMonth(year: u64) [12]u64 {
|
||
var daysInMonth = [_]u64{ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
|
||
|
||
if (isLeapYear(year)) {
|
||
daysInMonth[1] += 1;
|
||
}
|
||
|
||
return daysInMonth;
|
||
}
|
||
|
||
fn calculateYearAndDayOfYear(days: u64) struct { year: u64, dayOfYear: u64 } {
|
||
var year: u64 = 1970;
|
||
var d = days;
|
||
while (true) {
|
||
var daysInThisYear: u64 = if (isLeapYear(year)) 366 else 365;
|
||
if (d < daysInThisYear) break;
|
||
d -= daysInThisYear;
|
||
year += 1;
|
||
}
|
||
|
||
return .{ .year = year, .dayOfYear = d };
|
||
}
|
||
|
||
fn isLeapYear(year: u64) bool {
|
||
return (year % 4 == 0) and ((year % 100 != 0) or (year % 400 == 0));
|
||
}
|
||
|
||
fn declareDateVars(seconds: u64) DateTime {
|
||
var dt = DateTime{
|
||
.second = @mod(seconds, 60),
|
||
.minute = (@as(u64, seconds) / 60) % 60,
|
||
.hour = (seconds / 60 / 60) % 24,
|
||
.day = 0,
|
||
.month = 0,
|
||
.year = 0,
|
||
};
|
||
|
||
var days = seconds / 60 / 60 / 24;
|
||
|
||
var yearAndDayOfYear = calculateYearAndDayOfYear(days);
|
||
var year: u64 = yearAndDayOfYear.year;
|
||
var dayOfYear: u64 = yearAndDayOfYear.dayOfYear;
|
||
|
||
var month: u64 = 0;
|
||
var daysInMonth = getDaysInMonth(year);
|
||
|
||
while (dayOfYear >= daysInMonth[month]) {
|
||
dayOfYear -= daysInMonth[month];
|
||
month += 1;
|
||
}
|
||
|
||
dt.month = month + 1;
|
||
dt.day = dayOfYear + 1;
|
||
dt.year = year;
|
||
return dt;
|
||
}
|
||
|
||
pub fn unixToDateTime(timestamp: u64) DateTime {
|
||
const seconds: u64 = timestamp;
|
||
return declareDateVars(seconds);
|
||
}
|
||
|
||
pub fn dateTimeToUnix(dateTime: DateTime) u64 {
|
||
var totalSeconds: u64 = 0;
|
||
totalSeconds += dateTime.second;
|
||
totalSeconds += dateTime.minute * 60;
|
||
totalSeconds += dateTime.hour * 60 * 60;
|
||
totalSeconds += (dateTime.day - 1) * 24 * 60 * 60;
|
||
|
||
var daysInMonth = getDaysInMonth(dateTime.year);
|
||
var i: u64 = 0;
|
||
while (i < dateTime.month - 1) {
|
||
totalSeconds += daysInMonth[i] * 24 * 60 * 60;
|
||
i += 1;
|
||
}
|
||
|
||
var j: u64 = 1970;
|
||
while (j < dateTime.year) {
|
||
if (isLeapYear(j)) totalSeconds += 366 * 24 * 60 * 60 else totalSeconds += 365 * 24 * 60 * 60;
|
||
j += 1;
|
||
}
|
||
|
||
return totalSeconds;
|
||
}
|
||
|
||
pub fn nanoToSecond(nano: u64) u64 {
|
||
var sec: u64 = @divTrunc(nano, 1_000_000_000);
|
||
return sec;
|
||
}
|
||
|
||
pub fn fmtDigit(n: u8) [2]u8 {
|
||
if (n < 10) {
|
||
return [_]u8{ '0', '0' + n };
|
||
}
|
||
var t = n / 10; // 0*
|
||
var o = n % 10; // *0
|
||
return [_]u8{ '0' + t, '0' + o };
|
||
}
|
||
|
||
test "test fmtDigit" {
|
||
var dig: u64 = 8;
|
||
var result = fmtDigit(@intCast(dig));
|
||
if (!std.mem.eql(u8, &result, &[_]u8{ '0', '8' })) std.debug.panic("エラー:fmtDigit = {s}\n", .{result});
|
||
try testing.expect(std.mem.eql(u8, &result, &[_]u8{ '0', '8' }));
|
||
}
|
||
|
||
test "test nanoToSecond" {
|
||
var result = nanoToSecond(1690514984429000696);
|
||
if (result != 1690514984) std.debug.panic("エラー:nanoToSecond = {}\n", .{result});
|
||
try testing.expect(result == 1690514984);
|
||
}
|
||
|
||
test "test unixToDateTime" {
|
||
var timestamp: u64 = 1633639452;
|
||
var result = unixToDateTime(timestamp);
|
||
|
||
if (result.year != 2021) std.debug.panic("エラー:unixToDateTime.year = {}\n", .{result.year});
|
||
try testing.expect(result.year == 2021);
|
||
if (result.month != 10) std.debug.panic("エラー:unixToDateTime.month = {}\n", .{result.month});
|
||
try testing.expect(result.month == 10);
|
||
if (result.day != 7) std.debug.panic("エラー:unixToDateTime.day = {}\n", .{result.day});
|
||
try testing.expect(result.day == 7);
|
||
if (result.hour != 20) std.debug.panic("エラー:unixToDateTime.hour = {}\n", .{result.hour});
|
||
try testing.expect(result.hour == 20);
|
||
if (result.minute != 44) std.debug.panic("エラー:unixToDateTime.minute = {}\n", .{result.minute});
|
||
try testing.expect(result.minute == 44);
|
||
if (result.second != 12) std.debug.panic("エラー:unixToDateTime.second = {}\n", .{result.second});
|
||
try testing.expect(result.second == 12);
|
||
}
|
||
|
||
test "test dateTimeToUnix" {
|
||
var timestamp: DateTime = .{
|
||
.year = 2021,
|
||
.month = 10,
|
||
.day = 7,
|
||
.hour = 20,
|
||
.minute = 44,
|
||
.second = 12,
|
||
};
|
||
var result = dateTimeToUnix(timestamp);
|
||
if (result != 1633639452) std.debug.panic("エラー:dateTimeToUnix= {}\n", .{result});
|
||
try testing.expect(result == 1633639452);
|
||
}
|