Reading Saved Data

At the end of this load file method, there is an if statement that is supposed to work similarly to an alarm clock. However, it never plays the sound even if the dates stored in the array match the datetime.now. What am I doing wrong?

if f <> Nil And f.Exists Then
  
  Try
    var tis as TextInputStream = TextInputStream.open(f)
    
    var buff as String
    var eveEntry as EventStorage
    var events() as EventStorage
    var tkey as String
    var dttt as DateTime
    
    Var classpropValues() As String
    Do
      buff = tis.ReadLine
      
      If buff.IndexOf(0,Chr(9)) = -1 then //new key for dictionary
        if events.LastIndex <> - 1 then
          
          var finalevent() as EventStorage
          
          For Each ev as EventStorage in events
            finalEvent.Add ev
          Next
          
          app.EventCategory.Value(tkey) = finalevent
          
          events.RemoveAll
        End If
        
        tkey=buff
        
      Else
        classpropValues = buff.ToArray(Chr(9))
        
        
        dttt = DateTime.FromString(classpropValues(1))
        
        eveEntry = new EventStorage(classpropValues(0), dttt, classpropValues(2))
        
        EventListbox.AddRow classpropValues(0), classpropValues(2)
        
        events.Add eveentry
        if eveentry.DateandTime = DateTime.Now Then
          clownhornsoundeffect_1.PlayLooping
          
        end if
      End if
    Loop Until tis.EndOfFile
    
    app.EventCategory.Value(tkey) = events
  catch e as IOException
    System.DebugLog e.Message
  end
end if

DateTime.Now is a value that is significant to the nanosecond level, so it is very unlikely that you’ll get an exact match. Comparing eveentry.DateandTime.SQLDateTime with DateTime.Now.SQLDateTime would get you closer.

1 Like

If ‘Now’ is ‘3 minutes past 5’,
and the stored time is ‘2 minutes past 5’ ,

even if you use SQLDateTime, that alarm isn’t going to go off: you are a minute late.

Probably you need to be a bit flexible.

Eg (pseudocode)

const AReasonableTime as integer = 60 * 10  // allow 10 minutes leeway
diff = NOW.totalseconds - TimeFromFile.totalseconds
if diff > 0 and diff < AReasonableTime then
//DING!

//now,  flag the event in the file as 'done', in case the process runs 
//again inside the 10 minute window?
//if you dont want to amend the file, record something unique about it 
//in your app and check whether it has been done on the next pass

end if

@Jeff_Tullin
I’m not entirely sure how you would get the seconds value. Would you do something like this?

const AReasonableTime as integer = 60 * 2

var diff as integer
diff = DateTime.now.Second. - eveEntry.DateandTime.Second

if diff >0 and diff < AReasonableTime then
  clownhornsoundeffect_1.PlayLooping
  
end if

.SecondsFrom1970

(The .second value will vary from 0 to 59)

@Jeff_Tullin
I changed it to .secondsFrom1970 but it gives me an error on the diff = line.

const AReasonableTime as integer = 60 * 2

var diff as integer
diff = DateTime.now.SecondsFrom1970 - eveEntry.DateandTime.SecondsFrom1970

if diff >0 and diff < AReasonableTime then
  clownhornsoundeffect_1.PlayLooping
  
end if

What is the error?

The following works fine (wait 5 seconds before clicking OK), so my best guess is the error is ‘nil object’ on the eveEntry object

dim diff as integer
dim olddt as new DateTime(datetime.Now)

msgbox ""
diff = DateTime.now.SecondsFrom1970 - olddt.SecondsFrom1970
msgbox diff.ToString

@Jeff_Tullin When I run the code the error says “An exception of class NillObjectException was not handled. The application must shut down.”

const AReasonableTime as integer = 60 * 2

dim diff as integer
diff = DateTime.now.SecondsFrom1970 - eveEntry.DateandTime.SecondsFrom1970

if diff >0 and diff < AReasonableTime then
  clownhornsoundeffect_1.PlayLooping
  
end if

It will be eveentry that is a nil object, as I mentioned above.
When do you initialise it?

@Jeff_Tullin
I figured it out. I was calling eveEntry outside of the statement it was declared in. Thanks for your help!