365
365
-- described via table direction should be +1 or -1
366
366
local function interval_increment (self , o , direction )
367
367
assert (direction == - 1 or direction == 1 )
368
- check_date (self , " interval_increment(date, object, -+1)" )
369
- assert (type (o ) == ' table' )
368
+ check_date (self , " interval_increment(date, object, direction)" )
369
+ if type (o ) ~= ' table' then
370
+ error (' interval_increment(date, object, direction) - object expected' , 2 )
371
+ end
370
372
371
373
local ym_updated = false
372
374
local dhms_updated = false
@@ -378,49 +380,43 @@ local function interval_increment(self, o, direction)
378
380
for key , value in pairs (o ) do
379
381
local handlers = {
380
382
years = function (v )
381
- assert ( v > 0 and v < 10000 )
383
+ check_range ( v , { 0 , 9999 }, key )
382
384
dt = cdt .dt_add_years (dt , direction * v , cdt .DT_LIMIT )
383
385
ym_updated = true
384
386
end ,
385
387
386
388
months = function (v )
387
- assert ( v > 0 and v < 13 )
389
+ check_range ( v , { 0 , 12 }, key )
388
390
dt = cdt .dt_add_months (dt , direction * v , cdt .DT_LIMIT )
389
391
ym_updated = true
390
392
end ,
391
393
392
394
weeks = function (v )
393
- assert ( v > 0 and v < 32 )
395
+ check_range ( v , { 0 , 52 }, key )
394
396
secs = secs + direction * 7 * v * SECS_PER_DAY
395
397
dhms_updated = true
396
398
end ,
397
399
398
400
days = function (v )
399
- assert ( v > 0 and v < 32 )
401
+ check_range ( v , { 0 , 31 }, key )
400
402
secs = secs + direction * v * SECS_PER_DAY
401
403
dhms_updated = true
402
404
end ,
403
405
404
406
hours = function (v )
405
- assert ( v >= 0 and v < 24 )
407
+ check_range ( v , { 0 , 23 }, key )
406
408
secs = secs + direction * 60 * 60 * v
407
409
dhms_updated = true
408
410
end ,
409
411
410
412
minutes = function (v )
411
- assert ( v >= 0 and v < 60 )
413
+ check_range ( v , { 0 , 59 }, key )
412
414
secs = secs + direction * 60 * v
413
415
end ,
414
416
415
417
seconds = function (v )
416
- assert (v >= 0 and v < 61 )
417
- local s , frac
418
- frac = v % 1
419
- if frac > 0 then
420
- s = v - (v % 1 )
421
- else
422
- s = v
423
- end
418
+ check_range (v , {0 , 60 }, key )
419
+ local s , frac = seconds_fraction (v )
424
420
secs = secs + direction * s
425
421
nsec = nsec + direction * frac * 1e9 -- convert fraction to nanoseconds
426
422
dhms_updated = true
448
444
449
445
local datetime_index = function (self , key )
450
446
local attributes = {
447
+ unixtime = function (self )
448
+ return self .secs
449
+ end ,
451
450
timestamp = function (self )
452
451
return self .secs + self .nsec / 1e9
453
452
end ,
@@ -486,6 +485,24 @@ local datetime_index = function(self, key)
486
485
return attributes [key ] ~= nil and attributes [key ](self ) or nil
487
486
end
488
487
488
+ local function datetime_newindex (self , key , value )
489
+ local attributes = {
490
+ unixtime = function (self , value )
491
+ self .secs = value
492
+ self .nsec , self .offset = 0 , 0
493
+ end ,
494
+ timestamp = function (self , value )
495
+ local secs , frac = seconds_fraction (value )
496
+ self .secs = secs
497
+ self .nsec = frac * 1e9
498
+ self .offset = 0
499
+ end ,
500
+ }
501
+ if attributes [key ] ~= nil then
502
+ attributes [key ](self , value )
503
+ end
504
+ end
505
+
489
506
local function datetime_new_raw (secs , nsec , offset )
490
507
local dt_obj = ffi .new (datetime_t )
491
508
dt_obj .secs = secs
@@ -537,50 +554,45 @@ local function datetime_new(o)
537
554
end ,
538
555
539
556
year = function (v )
540
- assert ( v > 0 and v < 10000 )
557
+ check_range ( v , { 1 , 9999 }, key )
541
558
y = v
542
559
ymd = true
543
560
end ,
544
561
545
562
month = function (v )
546
- assert ( v > 0 and v < 13 )
563
+ check_range ( v , { 1 , 12 }, key )
547
564
M = v
548
565
ymd = true
549
566
end ,
550
567
551
568
day = function (v )
552
- assert ( v > 0 and v < 32 )
569
+ check_range ( v , { 1 , 31 }, key )
553
570
d = v
554
571
ymd = true
555
572
end ,
556
573
557
574
hour = function (v )
558
- assert ( v >= 0 and v < 24 )
575
+ check_range ( v , { 0 , 23 }, key )
559
576
h = v
560
577
hms = true
561
578
end ,
562
579
563
580
minute = function (v )
564
- assert ( v >= 0 and v < 60 )
581
+ check_range ( v , { 0 , 59 }, key )
565
582
m = v
566
583
hms = true
567
584
end ,
568
585
569
586
second = function (v )
570
- assert (v >= 0 and v < 61 )
571
- frac = v % 1
572
- if frac > 0 then
573
- s = v - (v % 1 )
574
- else
575
- s = v
576
- end
587
+ check_range (v , {0 , 60 }, key )
588
+ s , frac = seconds_fraction (v )
577
589
frac = frac * 1e9 -- convert fraction to nanoseconds
578
590
hms = true
579
591
end ,
580
592
581
593
-- tz offset in minutes
582
594
tz = function (v )
583
- assert ( v >= 0 and v <= 720 )
595
+ check_range ( v , { 0 , 720 }, key )
584
596
offset = v
585
597
end
586
598
}
@@ -937,6 +949,7 @@ local datetime_mt = {
937
949
__sub = datetime_sub ,
938
950
__add = datetime_add ,
939
951
__index = datetime_index ,
952
+ __newindex = datetime_newindex ,
940
953
add = function (self , o )
941
954
self = interval_increment (self , o , 1 )
942
955
return self
0 commit comments