[m-rev.] for review: timestamps

Simon Taylor stayl at cs.mu.OZ.AU
Thu May 31 20:54:06 AEST 2001


Estimated hours taken: 1
Branches: main

library/time.m:
	Add functions to handle system independent timestamps,
	which are just strings with format "yyyy-mm-dd hh:mm:ss".
	These will be used by smart recompilation.

NEWS:
	Document the new library functions.

tests/hard_coded/time_test.{m,exp}:
	Add a test for the new functions.

Index: NEWS
===================================================================
RCS file: /home/mercury1/repository/mercury/NEWS,v
retrieving revision 1.211
diff -u -u -r1.211 NEWS
--- NEWS	2001/05/31 09:31:21	1.211
+++ NEWS	2001/05/31 10:16:39
@@ -29,6 +29,11 @@
   which meant that the functions which required that field (e.g. time__asctime,
   time__mktime) did not work.
 
+* We've added functions to time.m to handle operating system
+  independent timestamps:
+	time__time_t_to_timestamp, time__gmtime_to_timestamp,
+	time__timestamp_to_string, time__string_to_timestamp.
+
 Changes to the Mercury implementation:
 * We've fixed a long-standing bug in the handling of module imports.
   Previously, if `module1' imported `module2' which imported `module3' in
Index: library/time.m
===================================================================
RCS file: /home/mercury1/repository/mercury/library/time.m,v
retrieving revision 1.21
diff -u -u -r1.21 time.m
--- library/time.m	2001/05/31 09:11:26	1.21
+++ library/time.m	2001/05/31 10:46:56
@@ -37,6 +37,12 @@
 	% calendar times.
 :- type time_t.
 
+	% A `timestamp' is similar to a `time_t' except that
+	% timestamps are operating system independent. A timestamp
+	% string (obtained using time__timestamp_to_string) written
+	% on one system can be read on any other system.
+:- type timestamp.
+
 	% The `tm' type is a concrete type that represents calendar
 	% times, broken down into their constituent components.
 :- type tm
@@ -145,11 +151,34 @@
 :- func time__ctime(time_t) = string.
 
 %-----------------------------------------------------------------------------%
+
+	% time__time_t_to_timestamp(Time) = Timestamp:
+	%	Converts the calendar time value `Time' into a timestamp.
+	%	Equivalent to `gm_time_to_timestamp(gmtime(Time))'.
+:-func time__time_t_to_timestamp(time_t) = timestamp.
+
+	% time__gmtime_to_timestamp(TM) = Timestamp:
+	%	Converts the broken-down UTC time value `TM'
+	%	into a timestamp.
+:- func time__gmtime_to_timestamp(tm) = timestamp.
+
+	% time__timestamp_to_string(Timestamp) = String:
+	%	Converts `Timestamp' into a string with format
+	%	"yyyy-mm-dd hh:mm:ss", expressed as UTC. 
+:- func time__timestamp_to_string(timestamp) = string.
+
+	% time__string_to_timestamp(String) = Timestamp:
+	%	Converts a string formatted as "yyyy-mm-dd hh:mm:ss",
+	%	into a timestamp. Fails if `String' does not have the
+	%	correct format.
+:- func time__string_to_timestamp(string) = timestamp is semidet.
+
+%-----------------------------------------------------------------------------%
 %-----------------------------------------------------------------------------%
 
 :- implementation.
 
-:- import_module int, exception.
+:- import_module int, exception, string.
 
 % XXX The assumption that a C `time_t' can fit into a Mercury `MR_Integer'
 % is not very portable.
@@ -517,6 +546,102 @@
 "{
 	mercury::runtime::Errors::SORRY(""foreign code for this function"");
 }").
+
+%-----------------------------------------------------------------------------%
+
+	% A timestamp is a string formatted as "yyyy-mm-dd hh:mm:ss"
+	% representing a time expressed as UTC (Universal Coordinated Time).
+:- type timestamp == string.
+
+%:- func time__time_t_to_timestamp(time_t) = timestamp.
+
+time__time_t_to_timestamp(Time) =
+		time__gmtime_to_timestamp(time__gmtime(Time)).
+
+%:- func time__gmtime_to_timestamp(tm) = timestamp.
+
+time__gmtime_to_timestamp(tm(Sec, Min, Hrs, WD, MD, YD, Month, Year, Dst)) = 
+		time__gmtime_to_timestamp_2(Sec, Min, Hrs, WD, MD, YD,
+			Month, Year, maybe_dst_to_int(Dst)).
+
+:- func time__gmtime_to_timestamp_2(int, int, int, int,
+		int, int, int, int, int) = timestamp.
+
+:- pragma foreign_proc("C",
+	time__gmtime_to_timestamp_2(Sec::in, Min::in, Hrs::in, WD::in,
+		MD::in, YD::in, Mnt::in, Yr::in, N::in) = (Result::out),
+	[will_not_call_mercury],
+"{
+	MR_String result;
+	int size;
+	struct tm t;
+
+	t.tm_sec = Sec;
+	t.tm_min = Min;
+	t.tm_hour = Hrs;
+	t.tm_mon = Mnt;
+	t.tm_year = Yr;
+	t.tm_wday = WD;
+	t.tm_mday = MD;
+	t.tm_yday = YD;
+	t.tm_isdst = N;
+
+	size = sizeof ""yyyy-mm-dd hh:mm:ss"";
+	MR_allocate_aligned_string_msg(Result, size - 1, MR_PROC_LABEL);
+
+	strftime(Result, size, ""%Y-%m-%d %H:%M:%S"", &t);
+}").
+
+:- pragma foreign_proc("MC++",
+	time__gmtime_to_timestamp_2(_Sec::in, _Min::in, _Hrs::in, _WD::in,
+		_MD::in, _YD::in, _Month::in, _Year::in,
+		_N::in) = (_Result::out),
+	[will_not_call_mercury],
+"{
+	mercury::runtime::Errors::SORRY(""foreign code for this function"");
+}").
+
+%:- func time__timestamp_to_string(string) = timestamp.
+
+time__timestamp_to_string(Timestamp) = Timestamp.
+
+%:- func time__string_to_timestamp(string) = timestamp is semidet.
+
+time__string_to_timestamp(Timestamp) = Timestamp :-
+	string__length(Timestamp) `with_type` int =
+		string__length("yyyy-mm-dd hh:mm:ss"),
+
+	string__to_int(string__unsafe_substring(Timestamp, 0, 4), _),
+
+	string__unsafe_index(Timestamp, 4, '-'),
+
+	string__to_int(string__unsafe_substring(Timestamp, 5, 2), Month),
+	Month >= 1,
+	Month =< 12,
+
+	string__unsafe_index(Timestamp, 7, '-'),
+
+	string__to_int(string__unsafe_substring(Timestamp, 8, 2), Day),
+	Day >= 1,
+	Day =< 31,
+
+	string__unsafe_index(Timestamp, 10, ' '),
+
+	string__to_int(string__unsafe_substring(Timestamp, 11, 2), Hour),
+	Hour >= 0,
+	Hour =< 23,
+
+	string__unsafe_index(Timestamp, 13, ':'),
+
+	string__to_int(string__unsafe_substring(Timestamp, 14, 2), Minute),
+	Minute >= 0,
+	Minute =< 59,
+
+	string__unsafe_index(Timestamp, 16, ':'),
+
+	string__to_int(string__unsafe_substring(Timestamp, 17, 2), Second),
+	Second >= 0,
+	Second =< 61.	% Seconds 60 and 61 are for leap seconds.
 
 %-----------------------------------------------------------------------------%
 
Index: tests/hard_coded/time_test.exp
===================================================================
RCS file: /home/mercury1/repository/tests/hard_coded/time_test.exp,v
retrieving revision 1.1
diff -u -u -r1.1 time_test.exp
--- tests/hard_coded/time_test.exp	2001/05/31 09:11:30	1.1
+++ tests/hard_coded/time_test.exp	2001/05/31 10:32:20
@@ -1,3 +1,5 @@
 mktime succeeded
 Sun Jan  7 03:02:01 2001
 
+2001-01-07 03:02:01
+string_to_timestamp succeeded
Index: tests/hard_coded/time_test.m
===================================================================
RCS file: /home/mercury1/repository/tests/hard_coded/time_test.m,v
retrieving revision 1.1
diff -u -u -r1.1 time_test.m
--- tests/hard_coded/time_test.m	2001/05/31 09:11:30	1.1
+++ tests/hard_coded/time_test.m	2001/05/31 10:24:00
@@ -21,5 +21,16 @@
 	% Sunday 2001-01-07 03:02:01
 	{ TM = tm(1, 2, 3, 0, 7, 6, 0, 101, no) },
 	io__write_string(asctime(TM)),
-	io__nl.
+	io__nl,
+	
+	{ Timestamp = gmtime_to_timestamp(TM) },
+	{ TimestampString = timestamp_to_string(Timestamp) },
+	io__write_string(TimestampString),
+	io__nl,
+
+	( { string_to_timestamp(TimestampString) = Timestamp } ->
+		io__write_string("string_to_timestamp succeeded\n")
+	;
+		io__write_string("string_to_timestamp failed\n")
+	).
 
--------------------------------------------------------------------------
mercury-reviews mailing list
post:  mercury-reviews at cs.mu.oz.au
administrative address: owner-mercury-reviews at cs.mu.oz.au
unsubscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: unsubscribe
subscribe:   Address: mercury-reviews-request at cs.mu.oz.au Message: subscribe
--------------------------------------------------------------------------



More information about the reviews mailing list