109 lines
4.4 KiB
ObjectPascal
109 lines
4.4 KiB
ObjectPascal
PROGRAM Date_manipulation;
|
|
|
|
{$IFDEF FPC}
|
|
{$mode objfpc} (*) directive TO be used for defining classes (*)
|
|
{$m+} (*) directive TO be used for using constructor (*)
|
|
|
|
{$LONGSTRINGS ON} (*) aka {H+} = ansistring (*)
|
|
{$RANGECHECKS ON} (*) aka {$R+} (*)
|
|
{$S+} (*) Stack checking (REQUIRED for exceptions) (*)
|
|
{$TYPEDADDRESS ON} (*) aka {$T+} (*)
|
|
{$modeswitch exceptions} (*) Explicitly enable exceptions (*)
|
|
{$modeswitch advancedrecords}
|
|
{$ELSE}
|
|
{$APPTYPE CONSOLE}
|
|
{$ENDIF}
|
|
|
|
{$MACRO ON}
|
|
{$DEFINE nl := #13#10 }
|
|
{$DEFINE tab := #9 }
|
|
|
|
{$WARNINGS OFF W1033} (*) Stop `data loss from "UnicodeString" to "AnsiString"` messages (*)
|
|
{$WARN 6058 OFF} (*) Disable `not inlined` messages (*)
|
|
|
|
USES
|
|
SysUtils,
|
|
DateUtils,
|
|
StrUtils,
|
|
TZDB;
|
|
|
|
(*)
|
|
This program uses the tzdb unit by Alexandru Ciobanu.
|
|
Copyright (c) 2010-2020, Alexandru Ciobanu (alex+git@ciobanu.org)
|
|
All rights reserved.
|
|
This software is provided "as is" without any express or implied warranties.
|
|
Please refer to the license for usage terms.
|
|
|
|
(*)
|
|
|
|
|
|
FUNCTION ParseDateTime(CONST DateTimeStr: string; out TimeZone: string): TDateTime;
|
|
|
|
VAR
|
|
Parts : TStringArray ;
|
|
LMonths : TMonthNameArray ;
|
|
M, D, Y : Integer ;
|
|
TimePart: string ;
|
|
|
|
BEGIN
|
|
|
|
Parts := DateTimeStr.Split( [ ' ' ] ) ;
|
|
|
|
IF Length(Parts) <> 5 THEN
|
|
raise Exception.Create( 'Invalid date format' ) ;
|
|
|
|
(*) Extract Month using system long Month names (*)
|
|
LMonths := DefaultFormatSettings.LongMonthNames ;
|
|
M := 1 + IndexStr( Parts[ 0 ], LMonths ) ;
|
|
D := StrToInt( Parts[ 1 ] ) ;
|
|
Y := StrToInt( Parts[ 2 ] ) ;
|
|
|
|
(*) Handle time with possible space between time and AM/PM (*)
|
|
TimePart := Parts[3];
|
|
IF Pos('m', Parts[3]) = 0 THEN (*) If 'm' not found, combine parts (*)
|
|
TimePart := Parts[3] + Parts[4];
|
|
|
|
TimeZone := Parts[High(Parts)]; (*) Get timezone abbreviation (*)
|
|
|
|
Result := EncodeDateTime ( Y, M, D,
|
|
HourOf ( StrToTime( TimePart ) ),
|
|
MinuteOf ( StrToTime( TimePart ) ), 0, 0 ) ;
|
|
END;
|
|
|
|
CONST
|
|
DATESTR = 'mmmm d yyyy h:nnam/pm' ;
|
|
|
|
VAR
|
|
OriginalDate: string;
|
|
LocalTime, UTC, NewTime: TDateTime;
|
|
NY_TZ, SYD_TZ: TBundledTimeZone;
|
|
NY_Abbrev, SYD_Abbrev: string;
|
|
|
|
BEGIN
|
|
|
|
OriginalDate := 'March 7 2009 7:30pm EST';
|
|
|
|
LocalTime := ParseDateTime( OriginalDate, NY_Abbrev ) ;
|
|
|
|
(*) Initialize timezones (*)
|
|
NY_TZ := TBundledTimeZone.GetTimeZone( 'America/New_York' ) ;
|
|
SYD_TZ := TBundledTimeZone.GetTimeZone( 'Australia/Sydney' ) ;
|
|
UTC := NY_TZ.ToUniversalTime( LocalTime ) ; (*) Convert to UTC (*)
|
|
UTC := IncHour( UTC, 12 ) ; (*) Add 12 hours in UTC (*)
|
|
|
|
NewTime := NY_TZ.ToLocalTime( UTC ) ; (*) back to local time with DST adjustment (*)
|
|
NY_Abbrev := NY_TZ.GetAbbreviation( UTC ) ;
|
|
|
|
(*) Convert TO Sydney time (*)
|
|
SYD_Abbrev := SYD_TZ.GetAbbreviation( SYD_TZ.ToLocalTime( UTC ) ) ;
|
|
|
|
(*) Output results (*)
|
|
|
|
WriteLn('Original time: ', FormatDateTime( DATESTR, LocalTime ), ' EST' ) ;
|
|
WriteLn('+12 hours: ', FormatDateTime( DATESTR, NewTime ), ' ', NY_Abbrev ) ;
|
|
WriteLn('Sydney time: ', FormatDateTime( DATESTR, SYD_TZ.ToLocalTime( UTC ) ), ' ', SYD_Abbrev ) ;
|
|
|
|
END. (*) Of PROGRAM Date_manipulation.pas (*)
|
|
|
|
(*)
|