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); }