[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH] New function posix_time32 to map timestamps
From: |
John Darrington |
Subject: |
[PATCH] New function posix_time32 to map timestamps |
Date: |
Thu, 12 Dec 2019 11:58:21 +0100 |
* doc/poke.texi (Date and Time Functions): New chapter.
* src/std.pk (posix_time32): New type.
* testsuite/poke.std/time32.pk: New file.
---
ChangeLog | 6 ++++
doc/poke.texi | 42 ++++++++++++++++++++++
src/std.pk | 83 ++++++++++++++++++++++++++++++++++++++++++++
testsuite/poke.std/time32.pk | 13 +++++++
4 files changed, 144 insertions(+)
create mode 100644 testsuite/poke.std/time32.pk
diff --git a/ChangeLog b/ChangeLog
index 0871856..92b1d31 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,11 @@
2019-12-15 John Darrington <address@hidden>
+ * doc/poke.texi (Date and Time Functions): New chapter.
+ * src/std.pk (posix_time32): New type.
+ * testsuite/poke.std/time32.pk: New file.
+
+2019-12-15 John Darrington <address@hidden>
+
* doc/poke.texi (Scripts): Elaborate on what scripts are
(and what they are not).
diff --git a/doc/poke.texi b/doc/poke.texi
index 06bf29b..e121597 100644
--- a/doc/poke.texi
+++ b/doc/poke.texi
@@ -109,6 +109,7 @@ The Standard Library
* String Functions:: Functions which deal with strings.
* Sorting Functions:: qsort.
* CRC Functions:: Cyclic Redundancy Checksums.
+* Date and Time Functions:: Functions for processing dates and times.
Hacking poke
* Writing Commands:: Extending poke with new commands.
@@ -4103,6 +4104,47 @@ defun crc32 = (byte[] @var{buf}) uint<32>: @{ @dots{} @}
This function returns the 32 bit CRC for the data contained in the
array @var{buf}.
+@node Date and Time Functions
+@chapter Date and Time Functions
+@cindex date
+@cindex time
+@cindex @code{posix_time32}
+
+Often a format encodes a timestamp expressed as the number of seconds
+since midnight, January@tie{}1st 1970@. You can map this
+simply as a @code{uint<32>}. However, the standard library provides
+a type which includes a pretty-printer (@pxref{Pretty Printers}) to
+display the date in a human readable format:
+
+@example
+deftype posix_time32 = struct
+@{
+ uint<32> seconds;
+
+ defun _print = void:
+ @{ @dots{} @}
+@}
+@end example
+
+@noindent
+When pretty printing is enabled, a mapped value of type @code{posix_time32}
will
+display similar to
+
+@example
+#<2019-Dec-12 8:54:56>
+@end example
+
+@noindent
+wheras when pretty printing is not enabled, this example would be displayed as:
+
+@example
+posix_time32 @{seconds=1576140896U@}
+@end example
+
+@noindent
+Note that timestamps of this type do not account for leap seconds and
+are agnostic towards timezone.
+
@node Writing Commands
@chapter Writing Commands
diff --git a/src/std.pk b/src/std.pk
index 0da1b93..d421d94 100644
--- a/src/std.pk
+++ b/src/std.pk
@@ -222,6 +222,89 @@ defun crc32 = (byte[] buf) uint<32>:
return update (0xffffffffU, buf) ^ 0xffffffffU;
}
+/*** Date and Time. */
+
+deftype posix_time32 = struct
+{
+ uint<32> seconds;
+
+ defun _print = void:
+ {
+ defun days_in_year = (int year) int:
+ {
+ if (year % 400 == 0) return 366;
+ if (year % 100 == 0) return 365;
+ if (year % 4 == 0) return 366;
+ return 365;
+ }
+
+ defun days_in_month = (int year, int month) int:
+ {
+ if (month < 0)
+ raise E_out_of_bounds;
+ if (month > 11)
+ raise E_out_of_bounds;
+
+ /* Deal with February. */
+ if (month == 1)
+ {
+ if (days_in_year (year) == 366)
+ return 29;
+ else
+ return 28;
+ }
+
+ /* 30 days hath Sept, Apr, June & Nov ... */
+ for (m in [8, 3, 5, 10])
+ {
+ if (month == m)
+ return 30;
+ }
+
+ return 31;
+ }
+
+ defvar month_names = ["Jan", "Feb", "Mar", "Apr", "May", "Jun",
+ "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
+
+ defvar year = 1970;
+ defvar month = 0;
+ defvar day = 0;
+ defvar hour = 0;
+ defvar minute = 0;
+ while (seconds >= 0)
+ {
+ if (seconds < 24 * 60 * 60)
+ {
+ hour = seconds / 3600;
+ seconds = seconds % 3600;
+ minute = seconds / 60;
+ seconds = seconds % 60;
+ break;
+ }
+ else if (seconds < days_in_month (year, month) * 24 * 60 * 60)
+ {
+ seconds = seconds - 24 * 60 * 60;
+ day = day + 1;
+ }
+ else if (seconds < days_in_year (year) * 24 * 60 * 60)
+ {
+ seconds = seconds - days_in_month (year, month) * 24 * 60 * 60;
+ month = month + 1;
+ }
+ else
+ {
+ seconds = seconds - days_in_year (year) * 24 * 60 * 60;
+ year = year + 1;
+ }
+ }
+ print "#<";
+ printf ("%<date-time:%i32d-%s-%i32d %i32d:%i32d:%i32d%>",
+ year, month_names[month], day + 1,
+ hour, minute, seconds);
+ print ">";
+ }
+};
/*** Miscellanea. */
diff --git a/testsuite/poke.std/time32.pk b/testsuite/poke.std/time32.pk
new file mode 100644
index 0000000..22d1046
--- /dev/null
+++ b/testsuite/poke.std/time32.pk
@@ -0,0 +1,13 @@
+/* { dg-do run } */
+
+/* { dg-command {.set pretty-print yes} } */
+/* { dg-command {.set endian host} } */
+
+
+/* { dg-data {i*} {0 1576140896} } */
+
+/* { dg-command {posix_time32 @ 0#B} } */
+/* { dg-output "#<1970-Jan-1 0:0:0>\n" } */
+
+/* { dg-command {posix_time32 @ 4#B} } */
+/* { dg-output "#<2019-Dec-12 8:54:56>\n" } */
--
2.11.0
- [PATCH] New function posix_time32 to map timestamps,
John Darrington <=