Skip to content

Commit ab53b41

Browse files
committed
[Bug 15821] com.livecode.date: Add the universal date.
Add a counterpart to `the local date` that returns the current UTC+00:00 date time.
1 parent 4e63df7 commit ab53b41

4 files changed

Lines changed: 98 additions & 21 deletions

File tree

docs/lcb/notes/feature-timezone.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,6 @@
22

33
## Date and time
44

5-
* `the local time` now returns a list with an additional 7th element.
6-
This is the local time zone's offset from UTC, in seconds.
5+
* `the local date` now returns a list with an additional 7th element. This is the local time zone's offset from UTC, in seconds.
6+
7+
* The new `the universal date` expression provides the date in the UTC+00:00 timezone. It returns a list in the same format as `the local date`.

libscript/src/date.mlc

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ module com.livecode.date
2525
use com.livecode.foreign
2626

2727
public foreign handler MCDateExecGetLocalDate(out rDateTime as List) returns nothing binds to "<builtin>"
28+
public foreign handler MCDateExecGetUniversalDate(out rDateTime as List) returns nothing binds to "<builtin>"
2829
public foreign handler MCDateExecGetUniversalTime(out rSeconds as CDouble) returns nothing binds to "<builtin>"
2930

3031
/*
@@ -49,6 +50,8 @@ elements of the list are:
4950
* The second (0-59)
5051
* The offset from UTC in seconds
5152

53+
References: UniversalDate (expression)
54+
5255
Tags: Date and time
5356
*/
5457
syntax LocalDate is expression
@@ -57,6 +60,31 @@ begin
5760
MCDateExecGetLocalDate(output)
5861
end syntax
5962

63+
/*
64+
Summary: The UTC Gregorian date
65+
66+
Example:
67+
variable tDateTime as List
68+
put the universal date into tDateTime
69+
70+
variable tMinuteOfHour as Number
71+
put tDateTime[5] into tMinuteOfHour
72+
73+
Description:
74+
Returns the universal date (i.e. the current date in the UTC+00:00
75+
time zone) as a list of seven numeric components. The elements of the
76+
list are the same as for <LocalDate>.
77+
78+
References: LocalDate (expression)
79+
80+
Tags: Date and time
81+
*/
82+
syntax UniversalDate is expression
83+
"the" "universal" "date"
84+
begin
85+
MCDateExecGetUniversalDate(output)
86+
end syntax
87+
6088
/*Summary: The seconds
6189

6290
Example:

libscript/src/module-date.cpp

Lines changed: 55 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -28,17 +28,27 @@ along with LiveCode. If not see <http://www.gnu.org/licenses/>. */
2828

2929
#if defined(__WINDOWS__)
3030
static bool
31-
MCDateGetLocalTimeInfo(struct tm & r_timeinfo,
32-
long & r_timezone)
31+
MCDateGetTimeInfo(bool t_is_local,
32+
struct tm & r_timeinfo,
33+
long & r_timezone)
3334
{
34-
_get_timezone(&t_timezone);
35+
if (t_is_local)
36+
{
37+
_get_timezone(&r_timezone);
38+
}
39+
else
40+
{
41+
r_timezone = 0;
42+
}
3543

3644
time_t t_now;
3745
time(&t_now);
3846

3947
/* Windows doesn't have localtime_r(), but it does have an equivalent
4048
* function with the arguments in the opposite order! */
41-
if (0 != localtime_s(&r_timeinfo, &t_time))
49+
if (0 != (t_is_local
50+
? localtime_s(&r_timeinfo, &t_time)
51+
: gmtime_s(&r_timeinfo, &t_time)))
4252
{
4353
return false;
4454
}
@@ -48,13 +58,16 @@ MCDateGetLocalTimeInfo(struct tm & r_timeinfo,
4858

4959
#elif defined(__MAC__) || defined(__IOS__)
5060
static bool
51-
MCDateGetLocalTimeInfo(struct tm & r_timeinfo,
52-
long & r_timezone)
61+
MCDateGetTimeInfo(bool t_is_local,
62+
struct tm & r_timeinfo,
63+
long & r_timezone)
5364
{
5465
time_t t_now;
5566
time(&t_now);
5667

57-
if (NULL == localtime_r(&t_now, &r_timeinfo))
68+
if (NULL == (t_is_local
69+
? localtime_r(&t_now, &r_timeinfo)
70+
: gmtime_r(&t_now, &r_timeinfo)))
5871
{
5972
return false;
6073
}
@@ -66,37 +79,48 @@ MCDateGetLocalTimeInfo(struct tm & r_timeinfo,
6679

6780
#elif defined(__LINUX__) || defined(__ANDROID__) || defined(__EMSCRIPTEN__)
6881
static bool
69-
MCDateGetLocalTimeInfo(struct tm & r_timeinfo,
70-
long & r_timezone)
82+
MCDateGetTimeInfo(bool t_is_local,
83+
struct tm & r_timeinfo,
84+
long & r_timezone)
7185
{
7286
time_t t_now;
7387
time (&t_now);
7488

75-
if (NULL == localtime_r(&t_now, &r_timeinfo))
89+
if (NULL == (t_is_local
90+
? localtime_r(&t_now, &r_timeinfo)
91+
: gmtime_r(&t_now, &r_timeinfo)))
7692
{
7793
return false;
7894
}
7995

80-
/* FIXME This may be expensive, but is probably required if
81-
* MCDateGetLocalTimeInfo() is to behave properly over summer time
82-
* changes. */
83-
tzset();
84-
r_timezone = timezone;
96+
if (t_is_local)
97+
{
98+
/* FIXME This may be expensive, but is probably required if
99+
* MCDateGetTimeInfo() is to behave properly over summer time
100+
* changes. */
101+
tzset();
102+
r_timezone = timezone;
103+
}
104+
else
105+
{
106+
r_timezone = 0;
107+
}
85108

86109
return true;
87110
}
88111

89112
#else
90-
# error "MCDateGetLocalTimeInfo() not implemented for this platform"
113+
# error "MCDateGetTimeInfo() not implemented for this platform"
91114
#endif
92115

93-
extern "C" MC_DLLEXPORT_DEF void
94-
MCDateExecGetLocalDate (MCProperListRef & r_datetime)
116+
static void
117+
MCDateExecGetDate(bool t_is_local,
118+
MCProperListRef & r_datetime)
95119
{
96120
struct tm t_timeinfo;
97121
long t_timezone;
98122

99-
if (!MCDateGetLocalTimeInfo(t_timeinfo, t_timezone))
123+
if (!MCDateGetTimeInfo(t_is_local, t_timeinfo, t_timezone))
100124
{
101125
return;
102126
}
@@ -120,6 +144,18 @@ MCDateExecGetLocalDate (MCProperListRef & r_datetime)
120144
return;
121145
}
122146

147+
extern "C" MC_DLLEXPORT_DEF void
148+
MCDateExecGetLocalDate (MCProperListRef & r_datetime)
149+
{
150+
MCDateExecGetDate(true, r_datetime);
151+
}
152+
153+
extern "C" MC_DLLEXPORT_DEF void
154+
MCDateExecGetUniversalDate(MCProperListRef & r_datetime)
155+
{
156+
MCDateExecGetDate(false, r_datetime);
157+
}
158+
123159
extern "C" MC_DLLEXPORT_DEF void
124160
MCDateExecGetUniversalTime (double& r_time)
125161
{

tests/lcb/stdlib/date.lcb

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,16 @@ public handler TestLocalDate()
2828
test "local date second range" when tDate[6] >= 0 and tDate[6] <= 59
2929
end handler
3030

31+
public handler TestUniversalDate()
32+
variable tDate
33+
put the universal date into tDate
34+
test "utc date element count" when the number of elements in tDate is 7
35+
test "utc date month range" when tDate[2] >= 1 and tDate[2] <= 12
36+
test "utc date day range" when tDate[3] >= 1 and tDate[3] <= 31
37+
test "utc date hour range" when tDate[4] >= 0 and tDate[4] <= 23
38+
test "utc date minute range" when tDate[5] >= 0 and tDate[5] <= 59
39+
test "utc date second range" when tDate[6] >= 0 and tDate[6] <= 59
40+
test "utc date no gmt offset" when tDate[7] is 0
41+
end handler
42+
3143
end module

0 commit comments

Comments
 (0)