-- Copyright 1993-1998, by the Cecil Project -- Department of Computer Science and Engineering, University of Washington -- See the LICENSE file for license information. module TimeAndDate { (--DOC The `date_info' object provides hygienic access to the `current_time' function. A new `date_info' representing the current time is returned by the `date' function; a `date_info' object for a given time is constructed by the `new_date_info' method. Many aspects of the current time and date can be queried; the `_shortname' versions return 3-letter abbreviations of their `_name' equivalents. The numbers returned are zero-based (i.e., January is month 0 and Sunday is day 0). The `print_string' output for a `date_info' object is identical to the output of the Unix date command. --) prim c_++ { #include #include #if VORTEX_SUN4 || VORTEX_POWERPC extern "C" int gettimeofday(struct timeval*, struct timezone*); #endif }; -- returns time in seconds method current_time():int (** return_type(int), sends(), does_io **) { prim c_++: " struct timeval tbuf; struct timezone tzbuf; if (gettimeofday(&tbuf, &tzbuf) == -1) { // should fail and report error number fatalEnv(currentEnv, \"gettimeofday error\"); } #ifdef DISPATCHERS RETURN(asTaggedInt(tbuf.tv_sec)); #else BP(asTaggedInt(tbuf.tv_sec)); #endif " } method real_time(cl:&():void):int { let start_time:int := current_time(); eval(cl); let end_time:int := current_time(); end_time - start_time } -- takes time in seconds and converts it to a 11-tuple of data protected method current_time_data(seconds_oop@:int):indexed[dynamic] (** return_type(i_vector), sends(), does_io, formals_escape(f) **) { prim c_++: " time_t seconds = seconds_oop->asInt(); struct tm* data = localtime(&seconds); #if VORTEX_SUN4 || VORTEX_ALPHA OOP tm_zone = NEW_STRING(data->tm_zone); OOP tm_gmtoff = asTaggedInt(data->tm_gmtoff); #else OOP tm_zone = NEW_STRING(\"Unknown zone\"); OOP tm_gmtoff = asTaggedInt(-1); #endif RegisteredOOP tm_zone_(tm_zone); // in case of GC in vector alloc OOP v = NEW_VEC(11); VEC_ELEM(v,0,OOP) = asTaggedInt(data->tm_sec); VEC_ELEM(v,1,OOP) = asTaggedInt(data->tm_min); VEC_ELEM(v,2,OOP) = asTaggedInt(data->tm_hour); VEC_ELEM(v,3,OOP) = asTaggedInt(data->tm_mday); VEC_ELEM(v,4,OOP) = asTaggedInt(data->tm_mon); VEC_ELEM(v,5,OOP) = asTaggedInt(data->tm_year); VEC_ELEM(v,6,OOP) = asTaggedInt(data->tm_wday); VEC_ELEM(v,7,OOP) = asTaggedInt(data->tm_yday); VEC_ELEM(v,8,OOP) = data->tm_isdst ? BASE(true) : BASE(false); VEC_ELEM(v,9,OOP) = tm_zone; VEC_ELEM(v,10,OOP)= tm_gmtoff; #ifdef DISPATCHERS RETURN(v); #else BP(v); #endif " } template object date_info isa comparable[date_info]; protected field data(@:date_info):indexed[dynamic]; method new_date_info(time:int):date_info { concrete object isa date_info { data := current_time_data(time) } } method date():date_info { new_date_info(current_time()) } method =(d1@:date_info, d2@:date_info):bool { d1 == d2 | { d1.data = d2.data } } method seconds(d@:date_info):int { d.data!0 } method minutes(d@:date_info):int { d.data!1 } method hours(d@:date_info):int { d.data!2 } method day_of_month(d@:date_info):int { d.data!3 } method month_of_year(d@:date_info):int { d.data!4 } method month_of_year_name(d@:date_info):string { ["January","February","March","April","May","June","July", "August","September","October","November","December"] ! d.month_of_year } method month_of_year_shortname(d@:date_info):string { d.month_of_year_name.copy_from(0,3) } method year(d@:date_info):int { (d.data!5) + 1900 } method day_of_week(d@:date_info):int { d.data!6 } method day_of_week_name(d@:date_info):string { ["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"] ! d.day_of_week } method day_of_week_shortname(d@:date_info):string { d.day_of_week_name.copy_from(0,3) } method day_of_year(d@:date_info):int { d.data!7 } method is_daylight_savings_time(d@:date_info):bool { d.data!8 } method time_zone_name(d@:date_info):string { d.data!9 } method gmt_offset(d@:date_info):int { d.data!10 } method print_string(d@:date_info):string { -- output identical to unix date command d.day_of_week_shortname || " " || d.month_of_year_shortname || " " || d.day_of_month.print_string(2) || " " || d.hours.print_string(2) || ":" || pad_left(d.minutes.print_string, 2, '0') || ":" || pad_left(d.seconds.print_string, 2, '0') || " " || d.time_zone_name || " " || d.year.print_string } }