Fix gmtime() handling of times very near the limits of time_t.
The UTC time may be several hours before or after local time, and therefore the UTC time/date may be slightly outside the limits of what can be represented as a local time/date. This is now handled correctly. This also more generally fixes handling of negative seconds/minutes/hours, which is also applicable to mktime().
This commit is contained in:
parent
32c5fd94a1
commit
3b0c1c2149
112
time.asm
112
time.asm
|
@ -227,9 +227,13 @@ mk1 inx
|
||||||
*
|
*
|
||||||
* factor - compute the seconds since 13 Nov 1969 from date
|
* factor - compute the seconds since 13 Nov 1969 from date
|
||||||
*
|
*
|
||||||
|
* factor_second32 - alt entry point taking second as a
|
||||||
|
* signed 32-bit input value
|
||||||
|
*
|
||||||
* Inputs:
|
* Inputs:
|
||||||
* year,month,day,hour,minute,second - time to convert
|
* year,month,day,hour,minute,second - time to convert
|
||||||
* (each treated as a signed 16-bit value)
|
* (each treated as a signed 16-bit value, with the
|
||||||
|
* exception of second when using factor_second32)
|
||||||
*
|
*
|
||||||
* Outputs:
|
* Outputs:
|
||||||
* count - seconds since 13 Nov 1969 (signed 64-bit value)
|
* count - seconds since 13 Nov 1969 (signed 64-bit value)
|
||||||
|
@ -244,12 +248,18 @@ factor private
|
||||||
;
|
;
|
||||||
; sign-extend time components to 4 bytes
|
; sign-extend time components to 4 bytes
|
||||||
;
|
;
|
||||||
stz year+2
|
|
||||||
lda year
|
stz second+2
|
||||||
|
lda second
|
||||||
bpl lb0
|
bpl lb0
|
||||||
|
dec second+2
|
||||||
|
factor_second32 entry
|
||||||
|
lb0 stz year+2
|
||||||
|
lda year
|
||||||
|
bpl lb0a
|
||||||
dec year+2
|
dec year+2
|
||||||
lb0 stz month+2
|
lb0a stz month+2
|
||||||
lb0a stz day+2
|
stz day+2
|
||||||
lda day
|
lda day
|
||||||
bpl lb0b
|
bpl lb0b
|
||||||
dec day+2
|
dec day+2
|
||||||
|
@ -259,12 +269,8 @@ lb0b stz hour+2
|
||||||
dec hour+2
|
dec hour+2
|
||||||
lb0c stz minute+2
|
lb0c stz minute+2
|
||||||
lda minute
|
lda minute
|
||||||
bpl lb0d
|
|
||||||
dec minute+2
|
|
||||||
lb0d stz second+2
|
|
||||||
lda second
|
|
||||||
bpl lb0e
|
bpl lb0e
|
||||||
dec second+2
|
dec minute+2
|
||||||
;
|
;
|
||||||
; adjust for out-of-range month values
|
; adjust for out-of-range month values
|
||||||
;
|
;
|
||||||
|
@ -347,17 +353,24 @@ lb4 mul4 hour,#3600,t1 add in hours*3600
|
||||||
;
|
;
|
||||||
add_t1_to_count anop
|
add_t1_to_count anop
|
||||||
clc
|
clc
|
||||||
lda count
|
lda t1
|
||||||
adc t1
|
adc count
|
||||||
sta count
|
sta count
|
||||||
lda count+2
|
lda t1+2
|
||||||
adc t1+2
|
tax
|
||||||
|
adc count+2
|
||||||
sta count+2
|
sta count+2
|
||||||
bcc ret
|
lda #0
|
||||||
inc count+4
|
txy
|
||||||
bne ret
|
bpl ad1
|
||||||
inc count+6
|
dec a
|
||||||
ret rts
|
ad1 tay
|
||||||
|
adc count+4
|
||||||
|
sta count+4
|
||||||
|
tya
|
||||||
|
adc count+6
|
||||||
|
sta count+6
|
||||||
|
rts
|
||||||
end
|
end
|
||||||
|
|
||||||
****************************************************************
|
****************************************************************
|
||||||
|
@ -397,14 +410,13 @@ t equ 6
|
||||||
phx push time_t value to convert
|
phx push time_t value to convert
|
||||||
phy
|
phy
|
||||||
|
|
||||||
pha check if time tool is active
|
pha make space for status return/TZ prefs
|
||||||
_tiStatus
|
|
||||||
pla
|
|
||||||
bcs lb2
|
|
||||||
beq lb2
|
|
||||||
|
|
||||||
pha make space for TZ preferences record
|
|
||||||
pha
|
pha
|
||||||
|
_tiStatus check if time tool is active
|
||||||
|
bcs no_tz
|
||||||
|
lda 1,s
|
||||||
|
beq no_tz
|
||||||
|
|
||||||
pea 1 get one record element only (TZ offset)
|
pea 1 get one record element only (TZ offset)
|
||||||
|
|
||||||
tsc get time zone preference
|
tsc get time zone preference
|
||||||
|
@ -413,15 +425,7 @@ t equ 6
|
||||||
pha
|
pha
|
||||||
_tiGetTimePrefs
|
_tiGetTimePrefs
|
||||||
pla
|
pla
|
||||||
bcs lb1
|
bcs no_tz
|
||||||
|
|
||||||
sec adjust for time zone (standard time)
|
|
||||||
lda 5,s
|
|
||||||
sbc 1,s
|
|
||||||
sta 5,s
|
|
||||||
lda 7,s
|
|
||||||
sbc 3,s
|
|
||||||
sta 7,s
|
|
||||||
|
|
||||||
pha determine if it's daylight savings
|
pha determine if it's daylight savings
|
||||||
ph2 #$5E
|
ph2 #$5E
|
||||||
|
@ -429,20 +433,22 @@ t equ 6
|
||||||
pla
|
pla
|
||||||
lsr a
|
lsr a
|
||||||
lsr a
|
lsr a
|
||||||
bcs lb1
|
bcs doit
|
||||||
|
|
||||||
; clc
|
; clc
|
||||||
lda #-60*60 adjust for DST (+1 hour) if needed
|
lda #60*60 adjust for DST (+1 hour) if needed
|
||||||
adc 5,s
|
adc 1,s
|
||||||
sta 5,s
|
sta 1,s
|
||||||
lda #$ffff
|
lda #0
|
||||||
adc 7,s
|
adc 3,s
|
||||||
sta 7,s
|
sta 3,s
|
||||||
|
bra doit
|
||||||
|
|
||||||
lb1 pla remove time zone offset from stack
|
no_tz lda #0
|
||||||
pla
|
sta 1,s
|
||||||
|
sta 3,s
|
||||||
|
|
||||||
lb2 jsl ~gmlocaltime use common gmtime/localtime code
|
doit jsl ~gmlocaltime use common gmtime/localtime code
|
||||||
rtl
|
rtl
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -490,6 +496,8 @@ lb1 plb
|
||||||
pha push tm_isdst value
|
pha push tm_isdst value
|
||||||
phx push time_t value to convert
|
phx push time_t value to convert
|
||||||
phy
|
phy
|
||||||
|
pea 0 no time zone offset
|
||||||
|
pea 0
|
||||||
jsl ~gmlocaltime use common gmtime/localtime code
|
jsl ~gmlocaltime use common gmtime/localtime code
|
||||||
rtl
|
rtl
|
||||||
end
|
end
|
||||||
|
@ -499,6 +507,7 @@ lb1 plb
|
||||||
* ~gmlocaltime - common code for gmtime and localtime
|
* ~gmlocaltime - common code for gmtime and localtime
|
||||||
*
|
*
|
||||||
* Inputs:
|
* Inputs:
|
||||||
|
* tz_offset - offset of local time from desired time zone
|
||||||
* t - time_t value (# of seconds since 13 Nov 1969)
|
* t - time_t value (# of seconds since 13 Nov 1969)
|
||||||
* isdst - value for tm_isdst flag
|
* isdst - value for tm_isdst flag
|
||||||
*
|
*
|
||||||
|
@ -510,7 +519,7 @@ lb1 plb
|
||||||
~gmlocaltime private
|
~gmlocaltime private
|
||||||
using TimeCommon
|
using TimeCommon
|
||||||
|
|
||||||
csubroutine (4:t,2:isdst),0
|
csubroutine (4:tz_offset,4:t,2:isdst),0
|
||||||
phb
|
phb
|
||||||
phk
|
phk
|
||||||
plb
|
plb
|
||||||
|
@ -522,9 +531,12 @@ lb1 plb
|
||||||
stz month
|
stz month
|
||||||
stz hour
|
stz hour
|
||||||
stz minute
|
stz minute
|
||||||
stz second
|
lda tz_offset
|
||||||
|
sta second
|
||||||
|
lda tz_offset+2
|
||||||
|
sta second+2
|
||||||
lb1 inc year
|
lb1 inc year
|
||||||
jsr factor
|
jsr factor_second32
|
||||||
lda count+4
|
lda count+4
|
||||||
bne lb1b
|
bne lb1b
|
||||||
lda count+2
|
lda count+2
|
||||||
|
@ -535,7 +547,7 @@ lb1 inc year
|
||||||
lb1a ble lb1
|
lb1a ble lb1
|
||||||
lb1b dec year
|
lb1b dec year
|
||||||
lb2 inc month find the month
|
lb2 inc month find the month
|
||||||
jsr factor
|
jsr factor_second32
|
||||||
lda count+4
|
lda count+4
|
||||||
bmi lb2
|
bmi lb2
|
||||||
bne lb2b
|
bne lb2b
|
||||||
|
@ -546,7 +558,7 @@ lb2 inc month find the month
|
||||||
cmp t
|
cmp t
|
||||||
lb2a ble lb2
|
lb2a ble lb2
|
||||||
lb2b dec month
|
lb2b dec month
|
||||||
jsr factor recompute the factor
|
jsr factor_second32 recompute the factor
|
||||||
lda year set the year
|
lda year set the year
|
||||||
sta tm_year
|
sta tm_year
|
||||||
lda month set the month
|
lda month set the month
|
||||||
|
|
Loading…
Reference in New Issue