diff --git a/cpdf.ml b/cpdf.ml index 457051f..ca0cdb1 100644 --- a/cpdf.ml +++ b/cpdf.ml @@ -3703,15 +3703,15 @@ let make_xmp_date_from_components d = Printf.sprintf "%02i" d.offset_minutes in Cpdfstrftime.strftime - ~time:{Unix.tm_sec = d.second; - Unix.tm_min = d.minute; - Unix.tm_hour = d.hour; - Unix.tm_mday = d.day; - Unix.tm_mon = d.month - 1; - Unix.tm_year = d.year - 1900; - Unix.tm_wday = 0; - Unix.tm_yday = 0; - Unix.tm_isdst = false} + ~time:{Cpdfstrftime._tm_sec = d.second; + Cpdfstrftime._tm_min = d.minute; + Cpdfstrftime._tm_hour = d.hour; + Cpdfstrftime._tm_mday = d.day; + Cpdfstrftime._tm_mon = d.month - 1; + Cpdfstrftime._tm_year = d.year - 1900; + Cpdfstrftime._tm_wday = 0; + Cpdfstrftime._tm_yday = 0; + Cpdfstrftime._tm_isdst = false} "%Y-%m-%dT%H:%M:%S" ^ tzd diff --git a/cpdfmanual.pdf b/cpdfmanual.pdf index cc62eb3..0925711 100644 Binary files a/cpdfmanual.pdf and b/cpdfmanual.pdf differ diff --git a/cpdfmanual.tex b/cpdfmanual.tex index d9c7626..4142770 100644 --- a/cpdfmanual.tex +++ b/cpdfmanual.tex @@ -1454,8 +1454,8 @@ font size and color. \texttt{\%p} & "a.m" or "p.m"\\ \texttt{\%S} & Second of the minute (00--61)\\ \texttt{\%T} & Same as \%H:\%M:\%S\\ - \texttt{\%u} & Weekday (1--7, 1 = Monday)\\ - \texttt{\%w} & Weekday (0--6, 0 = Monday)\\ + \texttt{\%u} & Weekday (1--7, 1 = Sunday)\\ + \texttt{\%w} & Weekday (0--6, 0 = Sunday)\\ \texttt{\%Y} & Year (0000--9999)\\ \texttt{\%\%} & The \% character. \end{tabular} diff --git a/cpdfstrftime.ml b/cpdfstrftime.ml index 5996505..af3582f 100644 --- a/cpdfstrftime.ml +++ b/cpdfstrftime.ml @@ -1,8 +1,30 @@ (* C-Style strftime *) open Pdfutil +type t = + {_tm_sec : int; + _tm_min : int; + _tm_hour : int; + _tm_mday : int; + _tm_mon : int; + _tm_year : int; + _tm_wday : int; + _tm_yday : int; + _tm_isdst : bool} + +let t_of_unix u = + {_tm_sec = u.Unix.tm_sec; + _tm_min = u.Unix.tm_min; + _tm_hour = u.Unix.tm_hour; + _tm_mday = u.Unix.tm_mday; + _tm_mon = u.Unix.tm_mon; + _tm_year = u.Unix.tm_year; + _tm_wday = u.Unix.tm_wday; + _tm_yday = u.Unix.tm_yday; + _tm_isdst = u.Unix.tm_isdst} + let strf_A t = - match t.Unix.tm_wday with + match t._tm_wday with | 0 -> "Sunday" | 1 -> "Monday" | 2 -> "Tuesday" | 3 -> "Wednesday" | 4 -> "Thursday" | 5 -> "Friday" | 6 -> "Saturday" @@ -12,7 +34,7 @@ let strf_a t = String.sub (strf_A t) 0 3 let strf_B t = - match t.Unix.tm_mon with + match t._tm_mon with | 0 -> "January" | 1 -> "February" | 2 -> "March" | 3 -> "April" | 4 -> "May" | 5 -> "June" | 6 -> "July" | 7 -> "August" | 8 -> "September" | 9 -> "October" | 10 -> "November" @@ -22,56 +44,56 @@ let strf_b t = String.sub (strf_B t) 0 3 let strf_d t = - let s = string_of_int t.Unix.tm_mday in + let s = string_of_int t._tm_mday in if String.length s = 1 then "0" ^ s else s let strf_e t = - let s = string_of_int t.Unix.tm_mday in + let s = string_of_int t._tm_mday in if String.length s = 1 then " " ^ s else s let strf_H t = - let s = string_of_int t.Unix.tm_hour in + let s = string_of_int t._tm_hour in if String.length s = 1 then "0" ^ s else s let strf_I t = - let s = string_of_int (t.Unix.tm_hour mod 12) in + let s = string_of_int (t._tm_hour mod 12) in if String.length s = 1 then "0" ^ s else s let strf_j t = - let s = string_of_int t.Unix.tm_yday in + let s = string_of_int t._tm_yday in match String.length s with | 1 -> "00" ^ s | 2 -> "0" ^ s | _ -> s let strf_m t = - let s = string_of_int (t.Unix.tm_mon + 1) in + let s = string_of_int (t._tm_mon + 1) in if String.length s = 1 then "0" ^ s else s let strf_M t = - let s = string_of_int t.Unix.tm_min in + let s = string_of_int t._tm_min in if String.length s = 1 then "0" ^ s else s let strf_p t = - if t.Unix.tm_hour >= 12 then "p.m" else "a.m" + if t._tm_hour >= 12 then "p.m" else "a.m" let strf_S t = - let s = string_of_int t.Unix.tm_sec in + let s = string_of_int t._tm_sec in if String.length s = 1 then "0" ^ s else s let strf_T t = strf_H t ^ ":" ^ strf_M t ^ ":" ^ strf_S t let strf_u t = - match t.Unix.tm_wday with + match t._tm_wday with | 0 -> "7" | n -> string_of_int (n + 1) let strf_w t = - string_of_int t.Unix.tm_wday + string_of_int t._tm_wday let strf_Y t = - string_of_int (t.Unix.tm_year + 1900) + string_of_int (t._tm_year + 1900) let strf_percent _ = "%" @@ -82,9 +104,64 @@ let strftime_pairs = "%p", strf_p; "%S", strf_S; "%T", strf_T; "%u", strf_u; "%w", strf_w; "%Y", strf_Y; "%%", strf_percent] +(* On Posix, call out to 'date'. On Windows, read %DATE% and %TIME% with 'cmd + * /C echo %TIME%'. On failure, exception escapes to caller. *) +let contents_of_file filename = + let ch = open_in_bin filename in + let s = really_input_string ch (in_channel_length ch) in + close_in ch; + s + +let return_date () = + match Sys.os_type with + "Unix" -> + (* Call the POSIX 'date' program, redirected to a temp file, and parse. *) + let tempfile = Filename.temp_file "cpdf" "strftime" in + let command = Filename.quote_command "date" ~stdout:tempfile ["+%S-%M-%H-%d-%m-%Y-%w-%j"] in + let outcode = Sys.command command in + if outcode > 0 then raise (Failure "Date command returned non-zero exit code") else + let r = contents_of_file tempfile in + let get_int o l = int_of_string (String.sub r o l) in + Sys.remove tempfile; + {_tm_sec = get_int 0 2; + _tm_min = get_int 3 2; + _tm_hour = get_int 6 2; + _tm_mday = get_int 9 2; + _tm_mon = get_int 12 2 - 1; + _tm_year = get_int 15 4 - 1900; + _tm_wday = get_int 20 1; + _tm_yday = get_int 22 3 - 1; + _tm_isdst = false} + | _ -> + (* Run 'cmd /C echo %TIME%' and 'cmd /C echo %DATE%' *) + {_tm_sec = 0; + _tm_min = 0; + _tm_hour = 0; + _tm_mday = 1; + _tm_mon = 0; + _tm_year = 0; + _tm_wday = 0; + _tm_yday = 0; + _tm_isdst = false} + +let current_time () = + (*t_of_unix (Unix.localtime (Unix.gettimeofday ()))*) + try return_date () with + e -> + Printf.eprintf "Failed to retrieve time due to %s\n" (Printexc.to_string e); + {_tm_sec = 0; + _tm_min = 0; + _tm_hour = 0; + _tm_mday = 1; + _tm_mon = 0; + _tm_year = 0; + _tm_wday = 0; + _tm_yday = 0; + _tm_isdst = false} + let strftime ?time text = let time = - match time with None -> Unix.localtime (Unix.gettimeofday ()) | Some t -> t + match time with None -> current_time () | Some t -> t in let text = ref text in iter @@ -92,4 +169,3 @@ let strftime ?time text = text := string_replace_all search (replace_fun time) !text) strftime_pairs; !text - diff --git a/cpdfstrftime.mli b/cpdfstrftime.mli index aa6c86e..09dfd36 100644 --- a/cpdfstrftime.mli +++ b/cpdfstrftime.mli @@ -1,4 +1,19 @@ (** C-style strftime *) -(** This supports the following format specifiers: %a %A %b %B %s %e %H %I %j %m %M %p %S %T %u %w %Y %% *) -val strftime : ?time:Unix.tm -> string -> string +(** Supports the following format specifiers: + %a %A %b %B %s %e %H %I %j %m %M %p %S %T %u %w %Y %% *) + +(** Our version of Unix's tm, so Unix not required *) +type t = + {_tm_sec : int; + _tm_min : int; + _tm_hour : int; + _tm_mday : int; + _tm_mon : int; + _tm_year : int; + _tm_wday : int; + _tm_yday : int; + _tm_isdst : bool} + +(** If time omitted, the current time is used. *) +val strftime : ?time:t -> string -> string diff --git a/cpdftime.c b/cpdftime.c deleted file mode 100644 index e2adf0b..0000000 --- a/cpdftime.c +++ /dev/null @@ -1,62 +0,0 @@ -/**************************************************************************/ -/* */ -/* OCaml */ -/* */ -/* Xavier Leroy, projet Cristal, INRIA Rocquencourt */ -/* */ -/* Copyright 1996 Institut National de Recherche en Informatique et */ -/* en Automatique. */ -/* */ -/* All rights reserved. This file is distributed under the terms of */ -/* the GNU Lesser General Public License version 2.1, with the */ -/* special exception on linking described in the file LICENSE. */ -/* */ -/**************************************************************************/ - -/* This is not presently used. We need to bring in the win32unix implementation - * too and have the correct one chosen. Also need to copy across the OCaml - * interface to these functions */ - -#include -#include -#include -#include -#include - -double cpdf_unix_gettimeofday_unboxed(value unit) -{ - struct timeval tp; - gettimeofday(&tp, NULL); - return ((double) tp.tv_sec + (double) tp.tv_usec / 1e6); -} - -CAMLprim value cpdf_unix_gettimeofday(value unit) -{ - return caml_copy_double(cpdf_unix_gettimeofday_unboxed(unit)); -} - -static value cpdf_alloc_tm(struct tm *tm) -{ - value res; - res = caml_alloc_small(9, 0); - Field(res,0) = Val_int(tm->tm_sec); - Field(res,1) = Val_int(tm->tm_min); - Field(res,2) = Val_int(tm->tm_hour); - Field(res,3) = Val_int(tm->tm_mday); - Field(res,4) = Val_int(tm->tm_mon); - Field(res,5) = Val_int(tm->tm_year); - Field(res,6) = Val_int(tm->tm_wday); - Field(res,7) = Val_int(tm->tm_yday); - Field(res,8) = tm->tm_isdst ? Val_true : Val_false; - return res; -} - -CAMLprim value cpdf_unix_localtime(value t) -{ - time_t clock; - struct tm * tm; - clock = (time_t) Double_val(t); - tm = localtime(&clock); - return cpdf_alloc_tm(tm); -} -