Why have a tutorial just on dates and times?
Since Object Pascal and Javascript deal with dates quite differently. Sadly dates coming from JS to Pas2JS can be a issue. Because they are a surprisingly complex and rich subject matter.
The TDateTime data type in Pas2JS
In Delphi, Date and time processing depends on the TDateTime variable. It is used to hold a date and time combination. Smart Mobile Studio Smart Mobile Studio represents a DateTime type as a Float type, similar to TDateTime. The System.Types unit defines a type alias type TDateTime = Float.
DateTimetoStr (Now)
As I said, Object Pascal and Javascript deal with dates differently. The function DateTimetoStr (Now) return differents results.
Example:
DateTimetoStr (Now) using Delphi, result is: 7/25/2014 5:30:54 PM
DateTimetoStr (Now) using Pas2JS, result is: 2014-07-25 20:30:54
The problem is the fact it shows the UTC date and not the local date time. An workaround is illustrated by the following examples:
Code example: Display Local DateTime 1 - add SmartCL.RegEx unit.
function DateTimeToStr2 : string;
var md : Variant;
r1,r2,r3: TW3Regex;
begin
r1 := TW3Regex.Create('d{1,4}|m{1,4}|yy(?:yy)?|([HhMsTt])\1?|[LloSZ]|"[^"]*"|', 'g');
r2 := TW3Regex.Create('\b(?:[PMCEA][SDP]T|(?:Pacific|Mountain|Central|Eastern|Atlantic) (?:Standard|Daylight|Prevailing) Time|(?:GMT|UTC)(?:[-+]\d{4})?)\b', 'g');
r3 := TW3Regex.Create('[^-+\dA-Z]', 'g');
asm
var dF=function(){var t1=RegExp(@r1.FRegEx),t2=RegExp(@r2.FRegEx),t3=RegExp(@r3.FRegEx),p=function(v,l){v=String(v);l=l||2;while(v.length<l)v='0'+v;return v;};return function(dt,m1,u){if(arguments.length==1 && Object.prototype.toString.call(dt)=="[object String]" &&! '/\d/'.test(dt)){m1=dt;dt=undefined;} dt=dt?new Date(dt):new Date;if(isNaN(dt))throw SyntaxError('invalid date');m1=String(dF.m1s[m1]||m1||dF.m1s['default']);if(m1.slice(0,4)=='UTC:'){m1=m1.slice(4);u=true;} var _=u?'getUTC':'get',d=dt[_+'Date'](),D=dt[_+'Day'](),m=dt[_+'Month'](),y=dt[_+'FullYear'](),H=dt[_+'Hours'](),M=dt[_+'Minutes'](),s=dt[_+'Seconds'](),L=dt[_+'Milliseconds'](),o=u?0:dt.getTimezoneOffset(),flags={d:d,dd:p(d),mm:p(m+1),yyyy:y,hh:p(H%12||12),HH:p(H),MM:p(M),s:s,ss:p(s),l:p(L,3),L:p(L>99?Math.round(L/10):L),t:H<12?'a':'p',tt:H<12?'am':'pm',T:H<12?'A':'P',TT:H<12?'AM':'PM',Z:u?'UTC':(String(dt).match(t2)||['']).pop().replace(t3,''),o:(o>0?'-':'+')+p(Math.floor(Math.abs(o)/60)*100+Math.abs(o)%60,4),S:['th','st','nd','rd'][d%10>3?0:(d%100-d%10!=10)*d%10]};return m1.replace(t1,function($0){return $0 in flags?flags[$0]:$0.slice(1,$0.length-1);});};}();dF.m1s={};Date.prototype.format=function(u){return dF(this,u);};@md = new Date().format('yyyy-mm-dd HH:MM:ss');
end;
result := md;
end;
ShowMessage(DateTimeToStr2);
|
Result is: 2014-07-25 17:30:54
------------------------------------------------------------
Code example: Display Local DateTime 2 - add W3C.Date unit.
procedure TForm1.W3Button1Click(Sender: TObject);
var Date: JDate = JDate.Create;
begin
// Get local date time
// calculate local date & time
// Get local date time
WriteLn(DateTimeToStr( Date.AsDateTime)); // 2014-07-25 21:44:17
WriteLn(DateTimetoStr(Now)); // 2014-07-25 21:44:17
WriteLn(DateToStr( Date.AsDateTime)); // 2014-07-25
WriteLn(TimeToStr( Date.AsDateTime)); // 21:44:17
WriteLn(Date.toLocaleString); // 25/7/2014 18:44:17
// my local date time
myDate := EncodeDate(Date.getFullYear, Date.getMonth+1, Date.getDate)+EncodeTime(Date.getHours, Date.getMinutes, Date.getSeconds, Date.getMilliseconds);
WriteLn(DateTimeToStr(myDate)); // 2014-07-25 18:44:17
WriteLn(DateToStr(myDate)); // 2014-07-25
WriteLn(TimeToStr(myDate)); // 18:44:17
end;
|
Result is:
2014-07-25 21:44:17
2014-07-25 21:44:17
2014-07-25
21:44:17
25/7/2014 18:44:17
2014-07-25 18:44:17
2014-07-25
18:44:17
--------------------------------
function W3Button1Click(Self, Sender$9) {
var myDate = 0;
var Date$2 = null;
var Date$2 = new Date();
WriteLn(DateTimeToStr(JDateHelper$GetAsDateTime(Date$2)));
WriteLn(DateTimeToStr(Now()));
WriteLn(DateToStr(JDateHelper$GetAsDateTime(Date$2)));
WriteLn(TimeToStr(JDateHelper$GetAsDateTime(Date$2)));
WriteLn(Date$2.toLocaleString());
myDate = EncodeDate(Date$2.getFullYear(),Date$2.getMonth()+1,Date$2.getDate())+
EncodeTime(Date$2.getHours(),Date$2.getMinutes(),Date$2.getSeconds(),Date$2.getMilliseconds());
WriteLn(DateTimeToStr(myDate));
WriteLn(DateToStr(myDate));
WriteLn(TimeToStr(myDate));
}
function JDateHelper$GetAsDateTime(Self$7) {
return (Self$7.getTime()/86400000)+25569;
}
function JDateHelper$SetAsDateTime(Self$8, dt) {
Self$8.setTime((dt-25569)*86400000);
}
function Now() { var d=new Date(); return d.getTime()/8.64e7+25569 };
function EncodeTime(h,m,s,z) { return (h+(m+(s+z*0.001)/60)/60)/24 };
function EncodeDate(y,m,d) { return Math.round(Date.UTC(y,m-1,d)/864e5+25569) };
function DateToStr(v) { return FormatDateTime("yyyy-mm-dd", v) };
function DateTimeToStr(v) { return FormatDateTime("yyyy-mm-dd hh:nn:ss", v) };
function TimeToStr(v) { return FormatDateTime("hh:nn:ss", v) };
function FormatDateTime(fmt, v) {
function pad2(v) { return (v<10)?"0"+v:v; };
function pad3(v) { return (v<100)?"0"+pad2(v):v; };
var res="";
var dt=new Date((v-25569)*864e5);
if (isNaN(dt.getTime())) return "#VAL!";
var i=0;
var c, tok;
while (i<fmt.length) {
c=fmt.charAt(i);
tok="";
while ((fmt.charAt(i)==c)&&(i<fmt.length)) {
tok+=c;
i++;
}
switch (tok) {
case "d": res+=(dt.getUTCDate()); break;
case "dd": res+=pad2(dt.getUTCDate()); break;
case "ddd": res+=fmtShortDayNames[dt.getUTCDay()]; break;
case "dddd": res+=fmtLongDayNames[dt.getUTCDay()]; break;
case "m": res+=dt.getUTCMonth()+1; break;
case "mm": res+=pad2(dt.getUTCMonth()+1); break;
case "mmm": res+=fmtShortMonthNames[dt.getUTCMonth()]; break;
case "mmmm": res+=fmtLongMonthNames[dt.getUTCMonth()]; break;
case "yy": res+=pad2(dt.getUTCFullYear()%100); break;
case "yyyy": res+=dt.getUTCFullYear(); break;
case "h": res+=dt.getUTCHours(); break;
case "hh": res+=pad2(dt.getUTCHours()); break;
case "n": res+=dt.getUTCMinutes(); break;
case "nn": res+=pad2(dt.getUTCMinutes()); break;
case "s": res+=dt.getUTCSeconds(); break;
case "ss": res+=pad2(dt.getUTCSeconds()); break;
case "z": res+=dt.getUTCMilliseconds(); break;
case "zzz": res+=pad3(dt.getUTCMilliseconds()); break;
default: res+=tok;
}
}
return res;
}
|
Displaying FormatDateTime in Pas2JS
There are a number of routines that convert date and or time values to strings for display or file storage purposes, such as dateTimeToStr and TimeToString. But the most important is the FormatDateTime. It provides comprehensive formatting control.
Code example: FormatDateTime with Pas2JS
procedure TForm1.W3Button1Click(Sender: TObject);
var
myDate: Float;
begin
myDate := EncodeDate(2014, 7, 25) + EncodeTime(5, 6, 7, 8);
// Date only - numeric values with no leading zeroes (except year)
WriteLn(' d/m/yy = ' +
FormatDateTime('d/m/yy', myDate));
// Date only - numeric values with leading zeroes
WriteLn(' dd/mm/yy = ' +
FormatDateTime('dd/mm/yy', myDate));
// Use short names for the day, month, and add freeform text ('of')
WriteLn(' ddd d of mmm yyyy = ' +
FormatDateTime('ddd d of mmm yyyy', myDate));
// Use long names for the day and month
WriteLn('dddd d of mmmm yyyy = ' +
FormatDateTime('dddd d of mmmm yyyy', myDate));
// Use the ShortDateFormat settings only
WriteLn(' dddd = ' +
FormatDateTime('dddd', myDate));
WriteLn(' mmmmm = ' +
FormatDateTime('mmmm', myDate));
WriteLn(' yyyy = ' +
FormatDateTime('yyyy', myDate));
// Time only - numeric values with no leading zeroes
WriteLn(' h:n:s.z = ' +
FormatDateTime('h:n:s.z', myDate));
// Time only - numeric values with leading zeroes
WriteLn(' hh:nn:ss.zzz = ' +
FormatDateTime('hh:nn:ss.zzz', myDate));
// DateTime - numeric values with leading zeroes
WriteLn('dd-mm-yyyy hh:nn:ss = ' +
FormatDateTime('dd-mm-yyyy hh:nn:ss', myDate));
WriteLn('The meeting is on' + FormatDateTime(' dddd, mmmm d, yyyy, ' +
'at hh:nn:ss', StrToDateTime('2014-08-25 17:39:45')));
WriteLn(DayOfMonth(myDate));
WriteLn(DayOfTheWeek(myDate));
WriteLn(DayOfWeek(myDate));
WriteLn(DayOfYear(myDate));
end;
|
Result is:
d/m/yy = 25/7/14
dd/mm/yy = 25/07/14
ddd d of mmm yyyy = fri 25 of jul 2014
dddd d of mmmm yyyy = friday 25 of july 2014
dddd = friday
mmmmm = july
yyyy = 2014
h:n:s.z = 5:6:7.7
hh:nn:ss.zzz = 05:06:07.007
dd-mm-yyyy hh:nn:ss = 25-07-2014 05:06:07
The meeting is on monday, august 25, 2014, at 17:39:45
25
5
6
206
------------
Date and Time calculations
The largest benefit of TDateTime (Float) is the range of calculations Pas2JS can do for you. These can be found on the Pas2JS built-in functions.
Code example: Custom date functions with Pas2JS
function Today: Float;
begin
Result := Date;
end;
function Yesterday: Float;
begin
Result := Date - 1;
end;
function Tomorrow: Float;
begin
Result := Date + 1;
end;
procedure TForm1.W3Button1Click(Sender: TObject);
begin
WriteLn('Today is '+DateToStr(Today)); // Set to the start of the current day
WriteLn('Yesterday is '+DateToStr(Yesterday)); // Set to the start of yesterday
WriteLn('Tomorrow is '+DateToStr(Tomorrow)); // Set to the start of tomorrow
WriteLn('DateTimeToISO8601 is '+DateTimeToISO8601(Now())); Set to the current day and time
WriteLn('DateTimeToStr is '+DateTimeToStr(Now()));
WriteLn('DateToISO8601 is '+DateToISO8601(Now()));
WriteLn('DateToStr is '+DateToStr(Now()));
WriteLn('DateToWeekNumber is '+ IntToStr( DateToWeekNumber(Now())) );
WriteLn('DateToYearOfWeek is '+ IntToStr( DateToYearOfWeek(Now())) );
WriteLn('DayOfMonth is ' + IntToStr( DayOfMonth(Now())) );
WriteLn('DayOfTheWeek is '+ IntToStr( DayOfTheWeek(Now())) );
WriteLn('DayOfWeek is '+ IntToStr( DayOfWeek(Now())) );
WriteLn('DayOfYear is '+ IntToStr( DayOfYear(Now())) );
end;
|
Result is:
Today is 2014-07-20
Yesterday is 2014-07-19
Tomorrow is 2014-07-21
DateTimeToISO8601 is 2014-07-20T19:54Z
DateTimeToStr is 2014-07-20 19:54:03
DateToISO8601 is 2014-07-20
DateToStr is 2014-07-20
DateToWeekNumber is 29
DateToYearOfWeek is 2014
DayOfMonth is 20
DayOfTheWeek is 7
DayOfWeek is 1
DayOfYear is 201
--------------------------
Show Long and Short named date values
Delphi provides some useful day and month names, such as: LongDayNames, ShortDayNames, LongMonthNames, ShortMonthNames, etc. With Smart Mobile Studio, you have to define this names in your own code, for instance:
· | LongDayNames variable provides an array of full string names of the days of the week. |
It is important to note that these day arrays start with index 1 = Sunday. This is not a good standard (it is not ISO 8601 compliant), so be careful when using with ISO 8601 compliant routines such as DayOfTheWeek
· | ShortMonthNames variable provides an array of short string names of the months of the year. |
Note that these month name array start with index = 1.
Code example: Display the long day names
procedure TForm1.W3Button3Click(Sender: TObject);
var LongDayNames : array[1..7] of string = ['Sunday','Monday','Tuesday','Wednesday',
'Thursday','Friday','Saturday'];
myDate : Float;
day : string;
begin
myDate := EncodeDate(2014, 12, 25);
day := LongDayNames[DayOfWeek(myDate)];
ShowMessage('Christmas day 2014 is on a '+day);
end;
|
Result is: Christmas day 2014 is on a Thursday
------------------------------------------------------------
Code example: Display the short month names
procedure TForm1.W3Button2Click(Sender: TObject);
var
month : Integer;
ShortMonthNames : array[1..12] of string = ['Jan','Feb','Mar','Apr','May','Jun',
'Jul','Aug','Sep','Oct','Nov','Dec'];
begin
for month := 1 to 12 do // Display the short and long month names
begin
ShowMessage(ShortMonthNames[month]);
end;
end;
|
Result is:
Jan
Feb
Mar
Apr
May
Jun
Jul
Aug
Sep
Oct
Nov
Dec
------
TIP: If you use DateTimeToStr( ) function in your code, Pas2JS will generate this JS code which define theses variables: fmtShortDayNames, fmtLongDayNames, fmtShortMonthNames and fmtLongMonthNames.
Code example: Display long and short date names:
procedure TForm1.W3Button2Click(Sender: TObject);
var
m, d : Integer;
begin
for m := 0 to 11 do // Display the short and long month names
begin
asm
WriteLn(fmtShortMonthNames[@m]);
WriteLn(fmtLongMonthNames[@m]);
end;
end;
for d := 0 to 6 do // Display the short and long day names
begin
asm
WriteLn(fmtShortDayNames[@d]);
WriteLn(fmtLongDayNames[@d]);
end;
end;
end;
|
Result is:
------------
jan
january
feb
february
mar
march
apr
april
may
may
jun
june
jul
july
aug
august
sep
september
oct
october
nov
november
dec
december
sun
sunday
mon
monday
tue
tuesday
wed
wednesday
thu
thursday
fri
friday
sat
saturday
---------------
|