Posix implementation of non-Unix date getter
This commit is contained in:
parent
7de182229f
commit
d19187a072
18
cpdf.ml
18
cpdf.ml
|
@ -3703,15 +3703,15 @@ let make_xmp_date_from_components d =
|
||||||
Printf.sprintf "%02i" d.offset_minutes
|
Printf.sprintf "%02i" d.offset_minutes
|
||||||
in
|
in
|
||||||
Cpdfstrftime.strftime
|
Cpdfstrftime.strftime
|
||||||
~time:{Unix.tm_sec = d.second;
|
~time:{Cpdfstrftime._tm_sec = d.second;
|
||||||
Unix.tm_min = d.minute;
|
Cpdfstrftime._tm_min = d.minute;
|
||||||
Unix.tm_hour = d.hour;
|
Cpdfstrftime._tm_hour = d.hour;
|
||||||
Unix.tm_mday = d.day;
|
Cpdfstrftime._tm_mday = d.day;
|
||||||
Unix.tm_mon = d.month - 1;
|
Cpdfstrftime._tm_mon = d.month - 1;
|
||||||
Unix.tm_year = d.year - 1900;
|
Cpdfstrftime._tm_year = d.year - 1900;
|
||||||
Unix.tm_wday = 0;
|
Cpdfstrftime._tm_wday = 0;
|
||||||
Unix.tm_yday = 0;
|
Cpdfstrftime._tm_yday = 0;
|
||||||
Unix.tm_isdst = false}
|
Cpdfstrftime._tm_isdst = false}
|
||||||
"%Y-%m-%dT%H:%M:%S"
|
"%Y-%m-%dT%H:%M:%S"
|
||||||
^
|
^
|
||||||
tzd
|
tzd
|
||||||
|
|
BIN
cpdfmanual.pdf
BIN
cpdfmanual.pdf
Binary file not shown.
|
@ -1454,8 +1454,8 @@ font size and color.
|
||||||
\texttt{\%p} & "a.m" or "p.m"\\
|
\texttt{\%p} & "a.m" or "p.m"\\
|
||||||
\texttt{\%S} & Second of the minute (00--61)\\
|
\texttt{\%S} & Second of the minute (00--61)\\
|
||||||
\texttt{\%T} & Same as \%H:\%M:\%S\\
|
\texttt{\%T} & Same as \%H:\%M:\%S\\
|
||||||
\texttt{\%u} & Weekday (1--7, 1 = Monday)\\
|
\texttt{\%u} & Weekday (1--7, 1 = Sunday)\\
|
||||||
\texttt{\%w} & Weekday (0--6, 0 = Monday)\\
|
\texttt{\%w} & Weekday (0--6, 0 = Sunday)\\
|
||||||
\texttt{\%Y} & Year (0000--9999)\\
|
\texttt{\%Y} & Year (0000--9999)\\
|
||||||
\texttt{\%\%} & The \% character.
|
\texttt{\%\%} & The \% character.
|
||||||
\end{tabular}
|
\end{tabular}
|
||||||
|
|
108
cpdfstrftime.ml
108
cpdfstrftime.ml
|
@ -1,8 +1,30 @@
|
||||||
(* C-Style strftime *)
|
(* C-Style strftime *)
|
||||||
open Pdfutil
|
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 =
|
let strf_A t =
|
||||||
match t.Unix.tm_wday with
|
match t._tm_wday with
|
||||||
| 0 -> "Sunday" | 1 -> "Monday" | 2 -> "Tuesday"
|
| 0 -> "Sunday" | 1 -> "Monday" | 2 -> "Tuesday"
|
||||||
| 3 -> "Wednesday" | 4 -> "Thursday" | 5 -> "Friday"
|
| 3 -> "Wednesday" | 4 -> "Thursday" | 5 -> "Friday"
|
||||||
| 6 -> "Saturday"
|
| 6 -> "Saturday"
|
||||||
|
@ -12,7 +34,7 @@ let strf_a t =
|
||||||
String.sub (strf_A t) 0 3
|
String.sub (strf_A t) 0 3
|
||||||
|
|
||||||
let strf_B t =
|
let strf_B t =
|
||||||
match t.Unix.tm_mon with
|
match t._tm_mon with
|
||||||
| 0 -> "January" | 1 -> "February" | 2 -> "March" | 3 -> "April"
|
| 0 -> "January" | 1 -> "February" | 2 -> "March" | 3 -> "April"
|
||||||
| 4 -> "May" | 5 -> "June" | 6 -> "July" | 7 -> "August"
|
| 4 -> "May" | 5 -> "June" | 6 -> "July" | 7 -> "August"
|
||||||
| 8 -> "September" | 9 -> "October" | 10 -> "November"
|
| 8 -> "September" | 9 -> "October" | 10 -> "November"
|
||||||
|
@ -22,56 +44,56 @@ let strf_b t =
|
||||||
String.sub (strf_B t) 0 3
|
String.sub (strf_B t) 0 3
|
||||||
|
|
||||||
let strf_d t =
|
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
|
if String.length s = 1 then "0" ^ s else s
|
||||||
|
|
||||||
let strf_e t =
|
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
|
if String.length s = 1 then " " ^ s else s
|
||||||
|
|
||||||
let strf_H t =
|
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
|
if String.length s = 1 then "0" ^ s else s
|
||||||
|
|
||||||
let strf_I t =
|
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
|
if String.length s = 1 then "0" ^ s else s
|
||||||
|
|
||||||
let strf_j t =
|
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
|
match String.length s with
|
||||||
| 1 -> "00" ^ s
|
| 1 -> "00" ^ s
|
||||||
| 2 -> "0" ^ s
|
| 2 -> "0" ^ s
|
||||||
| _ -> s
|
| _ -> s
|
||||||
|
|
||||||
let strf_m t =
|
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
|
if String.length s = 1 then "0" ^ s else s
|
||||||
|
|
||||||
let strf_M t =
|
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
|
if String.length s = 1 then "0" ^ s else s
|
||||||
|
|
||||||
let strf_p t =
|
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 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
|
if String.length s = 1 then "0" ^ s else s
|
||||||
|
|
||||||
let strf_T t =
|
let strf_T t =
|
||||||
strf_H t ^ ":" ^ strf_M t ^ ":" ^ strf_S t
|
strf_H t ^ ":" ^ strf_M t ^ ":" ^ strf_S t
|
||||||
|
|
||||||
let strf_u t =
|
let strf_u t =
|
||||||
match t.Unix.tm_wday with
|
match t._tm_wday with
|
||||||
| 0 -> "7"
|
| 0 -> "7"
|
||||||
| n -> string_of_int (n + 1)
|
| n -> string_of_int (n + 1)
|
||||||
|
|
||||||
let strf_w t =
|
let strf_w t =
|
||||||
string_of_int t.Unix.tm_wday
|
string_of_int t._tm_wday
|
||||||
|
|
||||||
let strf_Y t =
|
let strf_Y t =
|
||||||
string_of_int (t.Unix.tm_year + 1900)
|
string_of_int (t._tm_year + 1900)
|
||||||
|
|
||||||
let strf_percent _ = "%"
|
let strf_percent _ = "%"
|
||||||
|
|
||||||
|
@ -82,9 +104,64 @@ let strftime_pairs =
|
||||||
"%p", strf_p; "%S", strf_S; "%T", strf_T; "%u", strf_u;
|
"%p", strf_p; "%S", strf_S; "%T", strf_T; "%u", strf_u;
|
||||||
"%w", strf_w; "%Y", strf_Y; "%%", strf_percent]
|
"%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 strftime ?time text =
|
||||||
let time =
|
let time =
|
||||||
match time with None -> Unix.localtime (Unix.gettimeofday ()) | Some t -> t
|
match time with None -> current_time () | Some t -> t
|
||||||
in
|
in
|
||||||
let text = ref text in
|
let text = ref text in
|
||||||
iter
|
iter
|
||||||
|
@ -92,4 +169,3 @@ let strftime ?time text =
|
||||||
text := string_replace_all search (replace_fun time) !text)
|
text := string_replace_all search (replace_fun time) !text)
|
||||||
strftime_pairs;
|
strftime_pairs;
|
||||||
!text
|
!text
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,19 @@
|
||||||
(** C-style strftime *)
|
(** 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 %% *)
|
(** Supports the following format specifiers:
|
||||||
val strftime : ?time:Unix.tm -> string -> string
|
%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
|
||||||
|
|
62
cpdftime.c
62
cpdftime.c
|
@ -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 <caml/mlvalues.h>
|
|
||||||
#include <caml/alloc.h>
|
|
||||||
#include <caml/fail.h>
|
|
||||||
#include <caml/memory.h>
|
|
||||||
#include <sys/time.h>
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in New Issue