Skip to content

Commit

Permalink
Fix reading of Igor DateTime
Browse files Browse the repository at this point in the history
* and add many more tests
* main problem was the handling of daylight saving offsets
* a different result is required when offsets are enforced
* also added tz to all tests since these are otherwise not reproducible
  • Loading branch information
jefferis committed Aug 4, 2024
1 parent a2f2812 commit 576ceed
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 9 deletions.
3 changes: 2 additions & 1 deletion DESCRIPTION
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ Description: Provides function to read data from the 'Igor Pro' data analysis
https://github.com/SilverLabUCL/NeuroMatic for details.
Imports:
bitops,
tools
tools,
timechange
Suggests:
spelling,
testthat
Expand Down
26 changes: 20 additions & 6 deletions R/ReadIgorBinary.R
Original file line number Diff line number Diff line change
Expand Up @@ -338,12 +338,26 @@ read.pxp<-function(pxpfile,regex,ReturnTimeSeries=FALSE,Verbose=FALSE,
i
}

igor_date_origin<-as.numeric(ISOdate(1904,1,1,hour=0,tz=""))

.convertIgorDate<-function(dateval){
dateval=dateval+igor_date_origin
class(dateval)<-"POSIXct"
dateval
# internal function to convert Igor dates
# these are expressed in seconds since 1904-01-01 in the local timezone
# note that we provide a tz argument to ensure that tests give the same
# results regardless of the local timezone of the test machine
.convertIgorDate<-function(dateval, tz=""){
igor_origin=ISOdatetime(1904,1,1,hour=0,min = 0, sec=0, tz=tz)
igor_origin_utc=ISOdatetime(1904,1,1,hour=0,min = 0, sec=0, tz='GMT')
origin_offset=as.numeric(igor_origin)-as.numeric(igor_origin_utc)

dateval=dateval+as.numeric(igor_origin)
res=as.POSIXct(dateval, tz = tz)
# this takes the same clock time (ie hms) but switches time zone, thereby
# changing the moment in time
res_utc=timechange::time_force_tz(res, tz = 'GMT')
res_offset=as.numeric(res)-as.numeric(res_utc)

# DST correction
dst_correction=origin_offset-res_offset
res=res-dst_correction
res
}

# enum PackedFileRecordType {
Expand Down
17 changes: 15 additions & 2 deletions tests/testthat/test-ibw.R
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,26 @@ test_that("Read Igor v2 file", {
})

test_that("Processing of dates", {
expect_equivalent(.convertIgorDate(3444214517),as.POSIXct("2013-02-20 14:15:17"))
# when in GMT timezone (Banjul, The Gambia) or BST Igor says
# print secs2Time(3444214517, 3)
# 14:15:17
expect_equivalent(.convertIgorDate(3444214517, tz="GMT"),as.POSIXct("2013-02-20 14:15:17", tz = 'GMT'))
expect_equivalent(.convertIgorDate(3444214517, tz="GMT"),as.POSIXct("2013-02-20 14:15:17", tz = 'GMT'))
expect_equivalent(.convertIgorDate(3444214517, tz="Europe/London"),as.POSIXct("2013-02-20 14:15:17", tz = 'Europe/London'))
# from nm20120811c1_016.pxp
# current implementation says 13:37 on my laptop, lmb cluster and mac in PDT
# but mtime of file and embedded time string is 12:37
# and this is also what I get on a sunos machine in PDT
# DISABLED due to OS dependent results that I cannot fix
expect_equivalent(.convertIgorDate(3427533421),as.POSIXct("2012-08-11 13:37:01"))
expect_equivalent(.convertIgorDate(3427533421, tz = 'GMT'),as.POSIXct("2012-08-11 12:37:01", tz='GMT'))
expect_equivalent(.convertIgorDate(3427533421, tz = 'Europe/London'),as.POSIXct("2012-08-11 12:37:01", tz='Europe/London'))

# when in GMT timezone or BST Igor says
# print secs2Time(3805612788, 3)
# 10:39:48
expect_equivalent(.convertIgorDate(3805612788, tz='GMT'),as.POSIXct("2024-08-04 10:39:48", tz='GMT'))
expect_equivalent(.convertIgorDate(3805612788, tz='Europe/London'),as.POSIXct("2024-08-04 10:39:48", tz='Europe/London'))
expect_equivalent(.convertIgorDate(3805612788, tz='America/New_York'),as.POSIXct("2024-08-04 10:39:48", tz='America/New_York'))
})

test_that("Processing of funny null terminated strings", {
Expand Down

0 comments on commit 576ceed

Please sign in to comment.