Skip to content

Commit e67c868

Browse files
authored
Merge pull request #542 from 99NIMI/539-ldate-ldt-and-ltod-types-incorrect-units
#539 changed any date precision to nanoseconds
2 parents ce4f6ce + 29ed2d5 commit e67c868

13 files changed

+268
-111
lines changed

Cargo.lock

+149-53
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

book/src/datatypes.md

+8-8
Original file line numberDiff line numberDiff line change
@@ -76,16 +76,16 @@ Examples
7676
| Type name | Size | Internally stored as |
7777
|-----------------|--------|------------------------------------|
7878
| TIME | 64 bit | Timespan in nanoseconds |
79-
| TIME\_OF\_DAY | 64 bit | Milliseconds since Jan 1, 1970 UTC |
80-
| DATE | 64 bit | Milliseconds since Jan 1, 1970 UTC |
81-
| DATE\_AND\_TIME | 64 bit | Milliseconds since Jan 1, 1970 UTC |
79+
| TIME\_OF\_DAY | 64 bit | Nanoseconds since Jan 1, 1970 UTC |
80+
| DATE | 64 bit | Nanoseconds since Jan 1, 1970 UTC |
81+
| DATE\_AND\_TIME | 64 bit | Nanoseconds since Jan 1, 1970 UTC |
8282

8383
Note that the internal representation and sizes of these types are specific
8484
to RuSTy and not defined by the IEC61131 standard.
8585

8686
### DATE
8787
The `DATE` datatype is used to represent a Date in the Gregorian Calendar. Such a value is
88-
stored as an i64 with a precision in milliseconds and denotes the number of milliseconds
88+
stored as an i64 with a precision in nanoseconds and denotes the number of nanoseconds
8989
that have elapsed since January 1, 1970 UTC not counting leap seconds. DATE literals start
9090
with `DATE#` or `D#` followed by a date in the format of `yyyy-mm-dd`.
9191

@@ -96,8 +96,8 @@ Examples
9696

9797
### DATE_AND_TIME
9898
The `DATE_AND_TIME` datatype is used to represent a certain point in time in the Gregorian Calendar.
99-
Such a value is stored as an `i64` with a precision in milliseconds and denotes the
100-
number of milliseconds that have elapsed since January 1, 1970 UTC not counting leap seconds.
99+
Such a value is stored as an `i64` with a precision in nanoseconds and denotes the
100+
number of nanoseconds that have elapsed since January 1, 1970 UTC not counting leap seconds.
101101
DATE_AND_TIME literals start with `DATE_AND_TIME#` or `DT#` followed by a date and time in the
102102
format of `yyyy-mm-dd-hh:mm:ss`.
103103

@@ -110,8 +110,8 @@ Examples
110110

111111
### TIME_OF_DAY
112112
The `TIME_OF_DAY` datatype is used to represent a specific moment in time in a day.
113-
Such a value is stored as an `i64` value with a precision in milliseconds and denotes the
114-
number of milliseconds that have elapsed since January 1, 1970 UTC not counting leap seconds.
113+
Such a value is stored as an `i64` value with a precision in nanoseconds and denotes the
114+
number of nanoseconds that have elapsed since January 1, 1970 UTC not counting leap seconds.
115115
Hence this value is stored as a `DATE_AND_TIME` with the day fixed to 1970-01-01.
116116
`TIME_OF_DAY` literals start with `TIME_OF_DAY#` or `TOD#` followed by a time in the
117117
format of `hh:mm:ss`.

src/codegen/generators/date_time_util.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ pub fn calculate_time_nano(negative: bool, sec: f64, milli: f64, micro: f64, nan
2222
}
2323
}
2424

25-
/// calculates the milliseconds since 1970-01-01-00:00:00 for the given
25+
/// calculates the nanoseconds since 1970-01-01-00:00:00 for the given
2626
/// point in time
2727
pub fn calculate_date_time(
2828
year: i32,
@@ -37,7 +37,7 @@ pub fn calculate_date_time(
3737
.ymd_opt(year, month, day)
3838
.and_hms_milli_opt(hour, min, sec, milli)
3939
{
40-
return Ok(date_time.timestamp_millis());
40+
return Ok(date_time.timestamp_nanos());
4141
}
4242
Err(format!(
4343
"Invalid Date {}-{}-{}-{}:{}:{}.{}",

src/codegen/tests/snapshots/rusty__codegen__tests__code_gen_tests__date_comparisons.snap

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
source: src/codegen/tests/code_gen_tests.rs
3+
assertion_line: 493
34
expression: result
4-
55
---
66
; ModuleID = 'main'
77
source_filename = "main"
@@ -17,13 +17,13 @@ entry:
1717
%c = getelementptr inbounds %prg_interface, %prg_interface* %0, i32 0, i32 2
1818
%d = getelementptr inbounds %prg_interface, %prg_interface* %0, i32 0, i32 3
1919
%load_a = load i64, i64* %a, align 4
20-
%tmpVar = icmp sgt i64 %load_a, 1619827200000
20+
%tmpVar = icmp sgt i64 %load_a, 1619827200000000000
2121
%load_b = load i64, i64* %b, align 4
22-
%tmpVar1 = icmp sgt i64 %load_b, 1619897357000
22+
%tmpVar1 = icmp sgt i64 %load_b, 1619897357000000000
2323
%load_c = load i64, i64* %c, align 4
2424
%tmpVar2 = icmp sgt i64 %load_c, 156557000000000
2525
%load_d = load i64, i64* %d, align 4
26-
%tmpVar3 = icmp sgt i64 %load_d, 70157000
26+
%tmpVar3 = icmp sgt i64 %load_d, 70157000000000
2727
ret void
2828
}
2929

src/codegen/tests/snapshots/rusty__codegen__tests__code_gen_tests__program_with_date_assignment.snap

+9-9
Original file line numberDiff line numberDiff line change
@@ -16,18 +16,18 @@ entry:
1616
%x = getelementptr inbounds %prg_interface, %prg_interface* %0, i32 0, i32 1
1717
%y = getelementptr inbounds %prg_interface, %prg_interface* %0, i32 0, i32 2
1818
%z = getelementptr inbounds %prg_interface, %prg_interface* %0, i32 0, i32 3
19-
store i64 56190123, i64* %w, align 4
20-
store i64 56190123, i64* %w, align 4
19+
store i64 56190123000000, i64* %w, align 4
20+
store i64 56190123000000, i64* %w, align 4
2121
store i64 100012000000, i64* %x, align 4
2222
store i64 100012000000, i64* %x, align 4
23-
store i64 465436800000, i64* %y, align 4
23+
store i64 465436800000000000, i64* %y, align 4
2424
store i64 0, i64* %y, align 4
25-
store i64 465509714000, i64* %z, align 4
26-
store i64 58804123, i64* %z, align 4
27-
store i64 58804123, i64* %z, align 4
28-
store i64 946757700000, i64* %z, align 4
29-
store i64 946757700000, i64* %z, align 4
30-
store i64 946757708123, i64* %z, align 4
25+
store i64 465509714000000000, i64* %z, align 4
26+
store i64 58804123000000, i64* %z, align 4
27+
store i64 58804123000000, i64* %z, align 4
28+
store i64 946757700000000000, i64* %z, align 4
29+
store i64 946757700000000000, i64* %z, align 4
30+
store i64 946757708123000000, i64* %z, align 4
3131
ret void
3232
}
3333

src/codegen/tests/snapshots/rusty__codegen__tests__code_gen_tests__program_with_date_assignment_whit_short_datatype_names.snap

+6-6
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,15 @@ entry:
1616
%x = getelementptr inbounds %prg_interface, %prg_interface* %0, i32 0, i32 1
1717
%y = getelementptr inbounds %prg_interface, %prg_interface* %0, i32 0, i32 2
1818
%z = getelementptr inbounds %prg_interface, %prg_interface* %0, i32 0, i32 3
19-
store i64 56190123, i64* %w, align 4
20-
store i64 56190123, i64* %w, align 4
19+
store i64 56190123000000, i64* %w, align 4
20+
store i64 56190123000000, i64* %w, align 4
2121
store i64 100012000000, i64* %x, align 4
2222
store i64 100012000000, i64* %x, align 4
23-
store i64 465436800000, i64* %y, align 4
23+
store i64 465436800000000000, i64* %y, align 4
2424
store i64 0, i64* %y, align 4
25-
store i64 465509700000, i64* %z, align 4
26-
store i64 58808123, i64* %z, align 4
27-
store i64 58804123, i64* %z, align 4
25+
store i64 465509700000000000, i64* %z, align 4
26+
store i64 58808123000000, i64* %z, align 4
27+
store i64 58804123000000, i64* %z, align 4
2828
ret void
2929
}
3030

src/codegen/tests/snapshots/rusty__codegen__tests__code_gen_tests__program_with_long_date_assignment.snap

+5-5
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,12 @@ entry:
1818
%z = getelementptr inbounds %prg_interface, %prg_interface* %0, i32 0, i32 3
1919
store i64 100012000000, i64* %w, align 4
2020
store i64 100012000000, i64* %w, align 4
21-
store i64 465436800000, i64* %x, align 4
21+
store i64 465436800000000000, i64* %x, align 4
2222
store i64 0, i64* %x, align 4
23-
store i64 465509714000, i64* %y, align 4
24-
store i64 58804123, i64* %y, align 4
25-
store i64 56190123, i64* %z, align 4
26-
store i64 56190123, i64* %z, align 4
23+
store i64 465509714000000000, i64* %y, align 4
24+
store i64 58804123000000, i64* %y, align 4
25+
store i64 56190123000000, i64* %z, align 4
26+
store i64 56190123000000, i64* %z, align 4
2727
ret void
2828
}
2929

Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
source: src/codegen/tests/code_gen_tests.rs
3+
assertion_line: 454
34
expression: result
4-
55
---
66
; ModuleID = 'main'
77
source_filename = "main"
@@ -14,13 +14,13 @@ define void @prg(%prg_interface* %0) {
1414
entry:
1515
%y = getelementptr inbounds %prg_interface, %prg_interface* %0, i32 0, i32 0
1616
store i64 0, i64* %y, align 4
17-
store i64 3600000, i64* %y, align 4
18-
store i64 3600001, i64* %y, align 4
19-
store i64 3661000, i64* %y, align 4
20-
store i64 72900000, i64* %y, align 4
21-
store i64 72900000, i64* %y, align 4
22-
store i64 40260000, i64* %y, align 4
23-
store i64 40260000, i64* %y, align 4
17+
store i64 3600000000000, i64* %y, align 4
18+
store i64 3600001000000, i64* %y, align 4
19+
store i64 3661000000000, i64* %y, align 4
20+
store i64 72900000000000, i64* %y, align 4
21+
store i64 72900000000000, i64* %y, align 4
22+
store i64 40260000000000, i64* %y, align 4
23+
store i64 40260000000000, i64* %y, align 4
2424
ret void
2525
}
2626

tests/correctness/math_operators/addition.rs

+11-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use crate::{compile_and_run, MainType};
2+
use chrono::TimeZone;
23
use num::{Float, NumCast};
34

45
//addition tests
@@ -234,7 +235,7 @@ fn add_date_basic() {
234235
FUNCTION main : DATE
235236
VAR
236237
date_var : DATE := D#2021-01-01;
237-
date_10_days : DATE := 777600000;
238+
date_10_days : DATE := 777600000000000;
238239
result : DATE;
239240
END_VAR
240241
result := date_10_days + date_var;
@@ -245,7 +246,15 @@ fn add_date_basic() {
245246
let mut main = MainType::default();
246247

247248
let res: u64 = compile_and_run(prog.to_string(), &mut main);
248-
assert_eq!(res, 1610236800000);
249+
let date_var = chrono::Utc
250+
.ymd(2021, 1, 1)
251+
.and_hms(0, 0, 0)
252+
.timestamp_nanos() as u64;
253+
let date_10_days = chrono::Utc
254+
.ymd(1970, 1, 10)
255+
.and_hms(0, 0, 0)
256+
.timestamp_nanos() as u64;
257+
assert_eq!(res, date_10_days + date_var);
249258
}
250259

251260
#[test]

tests/correctness/math_operators/division.rs

+11-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use crate::{compile_and_run, MainType};
2+
use chrono::TimeZone;
23
use num::{Float, NumCast};
34

45
//--------------------------------------------------------------
@@ -196,7 +197,7 @@ fn division_date_basic() {
196197
FUNCTION main : DATE
197198
VAR
198199
date_var : DATE := D#2021-01-01;
199-
date_10_days : DATE := 777600000;
200+
date_10_days : DATE := 777600000000000;
200201
result,div_result : DATE;
201202
END_VAR
202203
div_result := date_10_days / 2;
@@ -208,7 +209,15 @@ fn division_date_basic() {
208209
let mut main = MainType::default();
209210

210211
let res: u64 = compile_and_run(prog.to_string(), &mut main);
211-
assert_eq!(res, 1609848000000);
212+
let date_var = chrono::Utc
213+
.ymd(2021, 1, 1)
214+
.and_hms(0, 0, 0)
215+
.timestamp_nanos() as u64;
216+
let date_10_days = chrono::Utc
217+
.ymd(1970, 1, 10)
218+
.and_hms(0, 0, 0)
219+
.timestamp_nanos() as u64;
220+
assert_eq!(res, date_var + date_10_days / 2);
212221
}
213222

214223
#[test]

tests/correctness/math_operators/mixed.rs

+31-6
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use crate::compile_and_run;
2+
use chrono::TimeZone;
23
use num::{Float, NumCast};
34

45
#[derive(Default)]
@@ -166,8 +167,8 @@ fn mixed_math_date_basic() {
166167
FUNCTION main : DATE
167168
VAR
168169
date_var : DATE := D#2021-01-01;
169-
date_10_days : DATE := 777600000;
170-
date_1_day : DATE := 86400;
170+
date_10_days : DATE := 777600000000000;
171+
date_1_day : DATE := 86400000000000;
171172
result : DATE;
172173
END_VAR
173174
result := date_var + date_10_days * 2 - date_1_day / 2;
@@ -178,7 +179,19 @@ fn mixed_math_date_basic() {
178179
let mut main = MainType::default();
179180

180181
let res: u64 = compile_and_run(prog.to_string(), &mut main);
181-
assert_eq!(res, 1611014356800);
182+
let date_var = chrono::Utc
183+
.ymd(2021, 1, 1)
184+
.and_hms(0, 0, 0)
185+
.timestamp_nanos() as u64;
186+
let date_10_days = chrono::Utc
187+
.ymd(1970, 1, 10)
188+
.and_hms(0, 0, 0)
189+
.timestamp_nanos() as u64;
190+
let date_1_day = chrono::Utc
191+
.ymd(1970, 1, 2)
192+
.and_hms(0, 0, 0)
193+
.timestamp_nanos() as u64;
194+
assert_eq!(res, date_var + date_10_days * 2 - date_1_day / 2);
182195
}
183196

184197
#[test]
@@ -187,8 +200,8 @@ fn mixed_math_dt_basic() {
187200
FUNCTION main : DT
188201
VAR
189202
date_var : DT := D#2021-01-01;
190-
date_10_days : DT := 777600000;
191-
date_1_day : DT := 86400;
203+
date_10_days : DT := 777600000000000;
204+
date_1_day : DT := 86400000000000;
192205
result : DT;
193206
END_VAR
194207
result := date_var + date_10_days * 2 - date_1_day / 2;
@@ -199,7 +212,19 @@ fn mixed_math_dt_basic() {
199212
let mut main = MainType::default();
200213

201214
let res: u64 = compile_and_run(prog.to_string(), &mut main);
202-
assert_eq!(res, 1611014356800);
215+
let date_var = chrono::Utc
216+
.ymd(2021, 1, 1)
217+
.and_hms(0, 0, 0)
218+
.timestamp_nanos() as u64;
219+
let date_10_days = chrono::Utc
220+
.ymd(1970, 1, 10)
221+
.and_hms(0, 0, 0)
222+
.timestamp_nanos() as u64;
223+
let date_1_day = chrono::Utc
224+
.ymd(1970, 1, 2)
225+
.and_hms(0, 0, 0)
226+
.timestamp_nanos() as u64;
227+
assert_eq!(res, date_var + date_10_days * 2 - date_1_day / 2);
203228
}
204229

205230
#[test]

tests/correctness/math_operators/multiplication.rs

+14-5
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use crate::{assert_almost_eq, compile_and_run, MainType};
2+
use chrono::TimeZone;
23
use num::{Float, NumCast};
34

45
//--------------------------------------------------------------
@@ -159,19 +160,27 @@ fn multiplication_date_basic() {
159160
FUNCTION main : DATE
160161
VAR
161162
date_var : DATE := D#2021-01-01;
162-
date_10_days : DATE := 777600000;
163-
result,div_result : DATE;
163+
date_10_days : DATE := 777600000000000;
164+
result,mul_result : DATE;
164165
END_VAR
165-
div_result := date_10_days * 2;
166-
result := date_var + div_result;
166+
mul_result := date_10_days * 2;
167+
result := date_var + mul_result;
167168
main := result;
168169
END_FUNCTION
169170
";
170171

171172
let mut main = MainType::default();
172173

173174
let res: u64 = compile_and_run(prog.to_string(), &mut main);
174-
assert_eq!(res, 1611014400000);
175+
let date_var = chrono::Utc
176+
.ymd(2021, 1, 1)
177+
.and_hms(0, 0, 0)
178+
.timestamp_nanos() as u64;
179+
let date_10_days = chrono::Utc
180+
.ymd(1970, 1, 10)
181+
.and_hms(0, 0, 0)
182+
.timestamp_nanos() as u64;
183+
assert_eq!(res, date_var + date_10_days * 2);
175184
}
176185

177186
#[test]

tests/correctness/math_operators/substraction.rs

+10-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use crate::{compile_and_run, MainType};
2+
use chrono::TimeZone;
23
use num::{Float, NumCast};
34

45
//--------------------------------------------------------------
@@ -207,7 +208,15 @@ fn substract_date_basic() {
207208
let mut main = MainType::default();
208209

209210
let res: u64 = compile_and_run(prog.to_string(), &mut main);
210-
assert_eq!(res, 777600000);
211+
let date_var = chrono::Utc
212+
.ymd(2021, 1, 1)
213+
.and_hms(0, 0, 0)
214+
.timestamp_nanos() as u64;
215+
let date_temp = chrono::Utc
216+
.ymd(2021, 1, 10)
217+
.and_hms(0, 0, 0)
218+
.timestamp_nanos() as u64;
219+
assert_eq!(res, date_temp - date_var);
211220
}
212221

213222
#[test]

0 commit comments

Comments
 (0)