mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-07-11 22:03:01 -06:00
Core: Improved timezone support, ScanWwwTime
git-svn-id: svn://ultimatepp.org/upp/trunk@7096 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
parent
6d28bd0678
commit
2a06d539c7
6 changed files with 119 additions and 8 deletions
|
|
@ -1,4 +1,6 @@
|
|||
String WwwFormat(Time tm);
|
||||
bool ScanWwwTime(const char *s, Time& tm);
|
||||
Time ScanWwwTime(const char *s);
|
||||
|
||||
String MIMECharsetName(byte charset);
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,10 @@
|
|||
|
||||
NAMESPACE_UPP
|
||||
|
||||
static const char *s_www_month[] = {
|
||||
"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
|
||||
};
|
||||
|
||||
String WwwFormat(Time tm)
|
||||
{
|
||||
static const char *dayofweek[] =
|
||||
|
|
@ -10,9 +14,54 @@ String WwwFormat(Time tm)
|
|||
{ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
|
||||
return String().Cat()
|
||||
<< dayofweek[DayOfWeek(tm)] << ", "
|
||||
<< (int)tm.day << ' ' << month[tm.month - 1]
|
||||
<< (int)tm.day << ' ' << s_www_month[tm.month - 1]
|
||||
<< ' ' << (int)tm.year
|
||||
<< ' ' << Sprintf("%2d:%02d:%02d +0100", tm.hour, tm.minute, tm.second);
|
||||
<< ' ' << Sprintf("%2d:%02d:%02d " + GetTimeZoneText(), tm.hour, tm.minute, tm.second);
|
||||
}
|
||||
|
||||
int FindMonth(const String& m)
|
||||
{
|
||||
for(int i = 0; i < 12; i++)
|
||||
if(s_www_month[i] == m)
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool ScanWwwTime(const char *s, Time& tm)
|
||||
{
|
||||
CParser p(s);
|
||||
try {
|
||||
if(p.IsId()) { // Skip day of week
|
||||
p.SkipTerm();
|
||||
p.Char(',');
|
||||
}
|
||||
tm.day = p.ReadInt(1, 31);
|
||||
int n = FindMonth(p.ReadId()) + 1;
|
||||
if(n < 1 || n > 12)
|
||||
return false;
|
||||
tm.month = n;
|
||||
tm.year = p.ReadInt(1, 4000);
|
||||
if(tm.year < 100)
|
||||
tm.year += 2000;
|
||||
tm.hour = p.ReadInt(0, 23);
|
||||
p.PassChar(':');
|
||||
tm.minute = p.ReadInt(0, 59);
|
||||
if(p.Char(':'))
|
||||
tm.second = p.ReadInt(0, 59);
|
||||
tm += 60 * (ScanTimeZone(p.GetPtr()) - GetTimeZone());
|
||||
}
|
||||
catch(CParser::Error) {
|
||||
return false;
|
||||
}
|
||||
return tm.IsValid();
|
||||
}
|
||||
|
||||
Time ScanWwwTime(const char *s)
|
||||
{
|
||||
Time tm;
|
||||
if(ScanWwwTime(s, tm))
|
||||
return tm;
|
||||
return Null;
|
||||
}
|
||||
|
||||
String MIMECharsetName(byte charset)
|
||||
|
|
|
|||
|
|
@ -611,12 +611,41 @@ bool SetSysTime(Time time)
|
|||
#endif
|
||||
}
|
||||
|
||||
int GetTimeZone()
|
||||
{
|
||||
static int zone;
|
||||
ONCELOCK {
|
||||
for(;;) { // This is somewhat ugly, but unified approach to get time zone offset
|
||||
Time t0 = GetSysTime();
|
||||
Time gmtime = GetUtcTime();
|
||||
Time ltime = GetSysTime();
|
||||
if(GetSysTime() - t0 < 1) { // Make sure that there is not much time between calls
|
||||
zone = (int)(ltime - gmtime) / 60; // Round to minutes
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return zone;
|
||||
}
|
||||
|
||||
String FormatTimeZone(int n)
|
||||
{
|
||||
return (n < 0 ? "-" : "+") + Format("%02.2d%02.2d", abs(n) / 60, abs(n) % 60);
|
||||
}
|
||||
|
||||
String GetTimeZoneText()
|
||||
{
|
||||
Time gmtime = GetUtcTime();
|
||||
Time ltime = GetSysTime();
|
||||
int d = (int)(ltime - gmtime) / 600;
|
||||
return Format("+%02.2d%01.1d0", d / 6, d % 6);
|
||||
return FormatTimeZone(GetTimeZone());
|
||||
}
|
||||
|
||||
int ScanTimeZone(const char *s)
|
||||
{
|
||||
int n = atoi(s);
|
||||
int hour = abs(n) / 100;
|
||||
int minutes = abs(n) % 100;
|
||||
if(hour >= 0 && hour <= 12 && minutes >= 0 && minutes < 60)
|
||||
return sgn(n) * (hour * 60 + minutes);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int GetLeapSeconds(Date dt)
|
||||
|
|
|
|||
|
|
@ -155,7 +155,10 @@ inline String AsString(const Time& time) { return Format(time); }
|
|||
|
||||
bool SetSysTime(Time time); // only root/sysadmin can do this...
|
||||
|
||||
int GetTimeZone();
|
||||
String GetTimeZoneText();
|
||||
int ScanTimeZoneText(const char *s);
|
||||
int ScanTimeZone(const char *s);
|
||||
|
||||
int GetLeapSeconds(Date dt);
|
||||
int64 GetUTCSeconds(Time tm);
|
||||
|
|
|
|||
|
|
@ -234,6 +234,23 @@ of leap years.&]
|
|||
[s2;%% Returns the Easter day for given [%-*@3 year].&]
|
||||
[s3;%% &]
|
||||
[s4; &]
|
||||
[s5;:GetTimeZone`(`): [@(0.0.255) int]_[* GetTimeZone]()&]
|
||||
[s2;%% Returns a local timezone as offset from GMT in minutes.&]
|
||||
[s3; &]
|
||||
[s4; &]
|
||||
[s5;:FormatTimeZone`(int`): [_^String^ String]_[* FormatTimeZone]([@(0.0.255) int]_[*@3 n])&]
|
||||
[s2;%% Formats timezone in common format, used e.g. in internet dates.&]
|
||||
[s3;%% &]
|
||||
[s4; &]
|
||||
[s5;:GetTimeZoneText`(`): [_^String^ String]_[* GetTimeZoneText]()&]
|
||||
[s2;%% Same as FormatTimeZone(GetTimeZone()).&]
|
||||
[s3; &]
|
||||
[s4; &]
|
||||
[s5;:ScanTimeZone`(const char`*`): [@(0.0.255) int]_[* ScanTimeZone]([@(0.0.255) const]_[@(0.0.255) c
|
||||
har]_`*[*@3 s])&]
|
||||
[s2;%% Scans timezone text to obtain offset in seconds.&]
|
||||
[s3;%% &]
|
||||
[s4; &]
|
||||
[s5;:GetLeapSeconds`(Date`): [@(0.0.255) int]_[* GetLeapSeconds]([_^Date^ Date]_[*@3 dt])&]
|
||||
[s2;%% Returns the number of leap seconds that has occured since
|
||||
the start of adding leap seconds till [%-*@3 dt].&]
|
||||
|
|
|
|||
|
|
@ -13,8 +13,19 @@ topic "Internet utility";
|
|||
[ {{10000@(113.42.0) [s0;%% [*@7;4 Internet format utility functions]]}}&]
|
||||
[s3; &]
|
||||
[s5;:WwwFormat`(Time`): [_^String^ String]_[* WwwFormat]([_^Time^ Time]_[*@3 tm])&]
|
||||
[s2;%% Returns Time in format commonly used in HTTP and other internet
|
||||
protocol, like `"Sun, 15 Apr 2012 16:00:25 GMT`".&]
|
||||
[s2;%% Returns Time in format defined by RFC2822, commonly used in
|
||||
HTTP and other internet protocol, like `"Sun, 15 Apr 2012 16:00:25
|
||||
GMT`".&]
|
||||
[s3;%% &]
|
||||
[s4; &]
|
||||
[s5;:ScanWwwTime`(const char`*`,Time`&`): [@(0.0.255) bool]_[* ScanWwwTime]([@(0.0.255) con
|
||||
st]_[@(0.0.255) char]_`*[*@3 s], [_^Time^ Time][@(0.0.255) `&]_[*@3 tm])&]
|
||||
[s2;%% Scans Time format as defined by RFC2822, returns true on success..&]
|
||||
[s3;%% &]
|
||||
[s4; &]
|
||||
[s5;:ScanWwwTime`(const char`*`): [_^Time^ Time]_[* ScanWwwTime]([@(0.0.255) const]_[@(0.0.255) c
|
||||
har]_`*[*@3 s])&]
|
||||
[s2;%% Scans Time format as defined by RFC2822, returns Null on failure.&]
|
||||
[s3;%% &]
|
||||
[s4; &]
|
||||
[s5;:MIMECharsetName`(byte`): [_^String^ String]_[* MIMECharsetName]([_^byte^ byte]_[*@3 char
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue