Skip to content
This repository

Add %z (timezone) handling in Date code. #34

Closed
wants to merge 1 commit into from

2 participants

Alok Menghrajani Quentin Bourgerie
Alok Menghrajani

This diff does not add total timezone handling (i.e. it doesn't allow you to parse the timezone from a string and/or mess around with timezone values). The main purpose of this diff is to have the ability to tell which timezone the server or client is running in, which is sometimes useful.

Alok Menghrajani Add %z (timezone) handling in Date code.
This diff does not add total timezone handling (i.e. it doesn't allow you to parse the timezone from a string and/or mess around with timezone values). The main purpose of this diff is to have the ability to tell which timezone the server or client is running in, which is sometimes useful.
90e2f5f
Alok Menghrajani

Note: I might have hit some bug with the bsl. If I try to make local_timezone_offset a nullary function, I end up with weird warnings:

opabsl/jsbsl/opabslgen_bslTime.js.pp:181: ERROR - Parse error. invalid return
return t.getTimezoneOffset();

(see https://gist.github.com/1734181).

Quentin Bourgerie

Alok, you have just missing ##args() on bsl register declaration.
Then I also correct Opa compile error (on date_private.opa)

see https://gist.github.com/1752783 it's just your https://gist.github.com/1734181 patch with corrections.

I commited the patch on our repository. (Sure I authored to you)

Thanks

Alok Menghrajani
Quentin Bourgerie
#register x \ y : 'a, 'b -> 'c

means "Register as 'x' the javascript function 'y' and it should respect the given signature ''a, 'b -> 'c'"
i.e is just like an alias.

This case is usefull when the function who want register is already defined.

In the case of 'now' indeed the implementation is just bellow the register declaration. And can be replaced by

##register now : -> time_t
##args()
{
...
}

2 -

##register x : 'a, 'b -> 'c
##args(a, b)
{
//code
}

means "Register as 'x' a javascript function with two arguments "a, b" and the following body"

Note : this way to register make some check (ex: cheking if the arity match).
And generates skeleton of javascript function.

I hope my explanations are clear enough.

Quentin.

Quentin Bourgerie BourgerieQuentin closed this February 08, 2012
Alok Menghrajani
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Showing 1 unique commit by 1 author.

Feb 03, 2012
Alok Menghrajani Add %z (timezone) handling in Date code.
This diff does not add total timezone handling (i.e. it doesn't allow you to parse the timezone from a string and/or mess around with timezone values). The main purpose of this diff is to have the ability to tell which timezone the server or client is running in, which is sometimes useful.
90e2f5f
This page is out of date. Refresh to see the latest.
8  libbase/time.ml
@@ -105,6 +105,14 @@ let local_wday time = (localtime time).Unix.tm_wday
105 105
 let local_yday time = (localtime time).Unix.tm_yday
106 106
 let local_isdst time = (localtime time).Unix.tm_isdst
107 107
 
  108
+let local_timezone_offset () =
  109
+  let t = Unix.time() in
  110
+  let gmt = Unix.gmtime(t) in
  111
+  let local = Unix.localtime(t) in
  112
+  let (gmt_s, _) = Unix.mktime(gmt) in
  113
+  let (local_s, _) = Unix.mktime(local) in
  114
+  int_of_float((gmt_s -. local_s) /. 60.0);;
  115
+
108 116
 let mktime ~year ~month ~day ~h ~min ~sec ~ms =
109 117
   let res =
110 118
     of_unix_time (
1  libbase/time.mli
@@ -52,6 +52,7 @@ val local_year : t -> int
52 52
 val local_wday : t -> int
53 53
 val local_yday : t -> int
54 54
 val local_isdst : t -> bool
  55
+val local_timezone_offset : unit -> int
55 56
 
56 57
 val mktime : year:int -> month:int -> day:int -> h:int -> min:int -> sec:int -> ms:int -> t
57 58
 
7  opabsl/jsbsl/bslTime.js
@@ -159,6 +159,13 @@ function now()
159 159
     return t.getHours();
160 160
 }
161 161
 
  162
+##register local_timezone_offset : time_t -> int
  163
+    ##args(f)
  164
+{
  165
+    var t = new Date(); t.setTime(f)
  166
+    return t.getTimezoneOffset();
  167
+}
  168
+
162 169
 ##register local_mday : time_t -> int
163 170
     ##args(f)
164 171
 {
3  opabsl/mlbsl/bslTime.ml
@@ -83,6 +83,9 @@
83 83
    ##register local_hour : time_t -> int
84 84
    let local_hour t = Time.local_hour (wrap t)
85 85
 
  86
+   ##register local_timezone_offset : time_t -> int
  87
+   let local_timezone_offset _ = Time.local_timezone_offset()
  88
+
86 89
    ##register local_mday : time_t -> int
87 90
    let local_mday t = Time.local_mday (wrap t)
88 91
 
27  stdlib/core/date/date.opa
@@ -424,6 +424,29 @@ type time_t = external
424 424
   get_hour : Date.date -> int = Date_private.time_local_hour
425 425
 
426 426
   /**
  427
+   * Returns the local timezone (+hhmm or -hhmm).
  428
+   *
  429
+   * On the server side, this will be a constant. On the client side
  430
+   * it will depend on whatever the user has set on their system.
  431
+   *
  432
+   * @return The local timezone (+hhmm or -hhmm).
  433
+  **/
  434
+  get_local_timezone : -> string = -> (
  435
+    t : Date.date = Date.now()
  436
+    delta : int = Date_private.time_local_timezone_offset(t)
  437
+    // delta is the timezone in minutes, so we need to convert it into
  438
+    // +hhmm or -hhmm. If delta is positive, the timezone is -hhmm. Otherwise
  439
+    // the timezone is +hhmm.
  440
+    h : int = Int.abs(delta) / 60
  441
+    m : int = mod(Int.abs(delta), 60)
  442
+    s : string = if delta > 0 then "-" else "+"
  443
+    p = {pad_with_zeros}
  444
+    h_str : string = Date_private.ToString.pad(h, p, p, 2)
  445
+    m_str : string = Date_private.ToString.pad(m, p, p, 2)
  446
+    "{s}{h_str}{m_str}"
  447
+  )
  448
+
  449
+  /**
427 450
    * Returns the weekday represented by this date interpreted in the local
428 451
    * time zone.
429 452
    * If you need to completely decompose a date consider using {!Date.to_human_readable}.
@@ -833,6 +856,7 @@ type time_t = external
833 856
    * - [%w] day of week (0..6); 0 is Sunday
834 857
    * - [%y] last two digits of year (00..99)
835 858
    * - [%Y] year (ex. 2010)
  859
+   * - [%z] +hhmm numeric timezone (e.g., -0400)
836 860
    *
837 861
    * By default, numeric fields are padded with zeroes. The following optional flags
838 862
    * may follow `%':
@@ -849,7 +873,6 @@ type time_t = external
849 873
    * - [%U] week number of year with Sunday as first day of week (00..53)
850 874
    * - [%V] week number of year with Monday as first day of week (01..53)
851 875
    * - [%W] week number of year with Monday as first day of week (00..53)
852  
-   * - [%z] +hhmm numeric timezone (e.g., -0400)
853 876
    * - [%:z] +hh:mm numeric timezone (e.g., -04:00)
854 877
    *
855 878
    * Also the padding directives are not supported:
@@ -975,7 +998,7 @@ type time_t = external
975 998
    *
976 999
    * For the purpose of parsing there are few differences in the interpretations
977 1000
    * of the format, compared to the format used for printing, see {!Date.try_generate_printer}:
978  
-   * - the directives '%C', '%u' and '%w' are not recognized,
  1001
+   * - the directives '%C', '%u', '%w' and '%z' are not recognized,
979 1002
    * - a non-empty sequence of spaces in the [format] can be matched by any (non-empty)
980 1003
    *   sequence of spaces in the input.
981 1004
    * - the padding flags ('_', '-' and '0') are ignored and all numerical values
5  stdlib/core/date/date_private.opa
@@ -105,6 +105,9 @@ import stdlib.core.parser
105 105
   time_local_hour : Date.date -> int =
106 106
     date_in(%%BslTime.local_hour%% : time_t -> int)   // Hours 0..23
107 107
 
  108
+  time_local_timezone_offset : Date.date -> int =
  109
+    date_in(%%BslTime.local_timezone_offset%% : time_t -> int)
  110
+
108 111
   time_local_mday : Date.date -> int =
109 112
     date_in(%%BslTime.local_mday%% : time_t -> int)   // Day of month 1..31
110 113
 
@@ -181,6 +184,7 @@ import stdlib.core.parser
181 184
       , ("x", true,  ((p, d) -> pad(Date.get_msec(d), p, {pad_with_zeros}, 3)))
182 185
       , ("y", false, ((_, d) -> pad(mod(Date.get_year(d), 100), {pad_with_zeros}, {pad_with_zeros}, 2)))
183 186
       , ("Y", true,  ((p, d) -> pad(Date.get_year(d), p, {pad_with_spaces}, 4)))
  187
+      , ("z", true, ((_, _) -> Date.get_local_timezone()))
184 188
       ]
185 189
 
186 190
     padding_flag_parser = parser
@@ -328,6 +332,7 @@ import stdlib.core.parser
328 332
       , ("x", parse_num(v -> d -> {d with ms = v}))
329 333
       , ("y", parse_num(v -> d -> {d with year=if v < 70 then 2000 + v else 1900 + v}))
330 334
       , ("Y", parse_num(v -> d -> {d with year=v}))
  335
+//      , ("z", *not supported for parsing*
331 336
       ]
332 337
 
333 338
     parse_directive_with((d, p)) =
Commit_comment_tip

Tip: You can add notes to lines in a file. Hover to the left of a line to make a note

Something went wrong with that request. Please try again.