Creating UTC DateTime?

Using Xojo 2019 R3.2 and trying to create a UTC DateTime object. I have looked at the recent thread on this matter: UTC time in which Greg O’Lone suggests just setting the GMTOffset to zero. That is all very nice, but DateTime does not seem to have a GMTOffset property! That appears to be part of the old Date object.

So, what does one do for DateTime objects? I have tried

Var utcTZ As New TimeZone("Etc/UTC")

Var utcDate As New DateTime(DateTime.Now.Year, _
DateTime.Now.Month, _
DateTime.Now.Day, _
DateTime.Now.Hour, _
DateTime.Now.Minute, _
DateTime.Now.Second, _
DateTime.Now.Nanosecond, utcTZ)

And it displays the DateTime.now hour, minute, and second values while showing the correct UTC offset when and interval between DateTime.Now and utcDate is computed. I need the actual UTC date and time to be displayed!

Help would be appreciated!

Many thanks
Jim Wagner
Oregon Research Electronics

Try:

Var utcTZ As New TimeZone("Etc/UTC")
Var utcDate as new DateTime(DateTime.Now.SecondsFrom1970, utcTZ)

That works. Local time is 15 hours, utcDate time is 22 hours. Seven hours difference is correct, here.

But oddly, when I do

var LocalDate as DateTime
LocalDate = DateTime.now
var Interval as DateInterval = LocalDate - utcDate

The interval shows a difference of zero (except for nanoseconds).

Many thanks!
Jim

Because regardless of time zone, there is still only one moment in time. Both objects reference the same moment, just in different time zones.

If you’re trying to find the offset, look at DateTime.Timezone.SecondsFromGMT.

I’m trying to understand enough so that I can set an arbitrary DateTime object to be different from the machine’s settings. Figured UTC would be a good starter since that is also a needed option.

Being Pacific Daylight Time, here, I am expecting to ultimately create a UTC DateTime that reads 7 hours (summer) difference from my machine. AlbertoD’s suggestion does that but missing the expected Interval value. I can live with that, though it does not advance my goal (very much), I don’t think, of understanding how to do it arbitrarily (like when a computer is carried from India to Nepal and the computer’s time zone is not changed, but I need to tell the app that I want it to use a time that is 30 minutes offset from what the computer shows).

Sorry for being so long winded. Time can be complicated!

Many thanks
Jim

DateTime’s SecondsFrom1970 is always GMT, which makes it really useful for storage and conversion. But I can’t say I’m really following your goal.

Thanks, Thom -
I’ll follow it from there.

Jim

From what I understand India is GMT+5:30 and Nepal is GMT+5:45 so I guess that you want to check the computer TimeZone and with that get/show a time in a different TZ, right?

You can create a new TZ using New TimeZone(seconds), so check the computer time, get the time zone SecondsFromGMT and +/- the seconds that you want.

Something like this:

Var now As DateTime = DateTime.Now
Var dtNew As DateTime
Var tzAbbr As String = now.Timezone.Abbreviation
Var tzSeconds As Integer
If tzAbbr = "America/Chicago" Then
  //want a datetime 30 minutes ahead
  tzSeconds = now.Timezone.SecondsFromGMT
  tzSeconds = tzSeconds + (30 * 60)
  dtNew = New DateTime(now.SecondsFrom1970, New TimeZone(tzSeconds))
Else
  //always use UTC - 3.5 hours, no daylight time change
  tzSeconds = - (3.5 * 60 * 60)
  dtNew = New DateTime(now.SecondsFrom1970, New TimeZone(tzSeconds))
End If
MessageBox(dtNew.ToString(DateTime.FormatStyles.Short, DateTime.FormatStyles.Short))

Thanks Alberto,

Jim

If that’s all you’re needing, then you don’t need to mess with time zones. Just add/subtract a DateInterval of 30 minutes from the current time.

I just discovered this, sort of. I can have the user enter the time to be synchronized with the machine time. The program then determines the interval between that time and the machine time, and whenever needed, makes a new datetime object using the interval and the machine’s timezone. Seems to work well.

Thanks
Jim

I think that still sounds wrong. You would use interval to adjust the time itself, and the zone to adjust how it is displayed.

Can you explain the problem again?
Is this only a “display” problem because the time zone is wrong or could it be that the computer can’t connect to the internet and the user can’t change the clock?

If the computer has the correct time but the wrong time zone, the user can’t adjust the time zone and wants your program to display a ‘correct’ time date, then you just need to adjust the time zone.

If the computer has a bad time and time zone, then you may ask the user for the correct time and the correct time zone, compare it with what the computer has and adjust the time and time zone as needed.

OK, I really need to back up a bit, here. The whole purpose is to set the clock in an attached instrument. Once set, I has no real purpose in the GUI. The computer on which the program is running may have a time setting that little relevance to the local time that the user want to use - that is, the computer may be set for time from several time zones away from the local. I want several options for setting that instrument clock: (1) computer time, what ever it might be, (2) UTC, (3) leave the instrument time at what ever it was, or (4) some arbitrary time (could be “local” time but does not have to be).

What ever time system the user chooses, I want the time to appear to be “live” so that if the user waits some minutes from setting to sending it to the instrument, it will still be close to true time. I have that running using a 1 second timer that recreates a new DateTime value for the appropriate time system and displays it for the user. When the user clicks an “UPDATE” button, the displayed value is sent to the instrument.

The “leave at current time” option means not updating the instrument, so we don’t need to bother about that. Computer time is easy because that is just DateTime.Now. UTC is also easy because that is DateTime( DateTime.Now.SecondsFrom1970, TimeZone(“Etc/UTC”) ). The challenge is the arbitrary time.

What I have been doing is creating a DateTime object using the entered year, etc, values and with the time zone set to DateTime.Now.TimeZone, the find the difference in SecondsFrom1970 for that DateTime and for DateTime.Now. Then I use that time offset to shift DateTime.Now to user time for the live display and to send to the instrument, when ever that happens. The important thing about user time is that the year, etc, numbers are the only important thing. It could be any time zone so long as the numbers read and update the instrument correctly.

Hope this helps to explain what I am trying to do, and to explain what I have done so far.

Thanks everyone! Further suggestions are ALWAYS appreciated.
Jim

Ok. Don’t overthink it. If (for example) I wanted to know the current time in US Pacific, I would do that with DateTime.Now(New TimeZone(“America/Los_Angeles”)). That’s it. You can do it with numeric offsets too, such as New TimeZone(-25200), but using the name allows the system to correct for daylight savings.

So it seems to me all you need to do is store the desired time zone name for the device. When you need to display the clock, just use Date.Now with that time zone.

Thom -

The issue, there, is that, in a remote location without internet access to the TimeZone database and its names, specifying the timezone’s correct name may be hard. Finding the numeric timezone offset may also be challenging. Daylight Savings Time is usually ignored by my users because they don’t want odd gaps or overlaps in months-long instrument recordings.

Jim

Keep the list with your app. This isn’t really an option, timestamps require 3 components: date, time, and time zone. If you’re missing any one piece, there’s no way to know which moment in time is being referenced.

Some questions:

  • Does the attached instrument handle Time Zones?

My printer has a clock that needs time and date but no time zone. I guess this is needed for the Fax part of it. If I send a Fax to Europe the Time/Date will be printed on the sending document at my local time but the receiving fax will also print a header with its local time. The difference could be 5-7 hours depending where I send the fax. I will not send my Fax time/date to match the receiving fax so I can live with that and I don’t think is a big problem.

If I give you this date and time “2022-03-14 14:15:00” it is missing the time zone, so you could ask for the correct time zone or assume is UTC.

  • Does the instrument needs a date or just time?

My oven has a clock/timer that only needs time 1-12 hours and if it is AM or PM. If this is the same with the instrument, I guess the people using it want to have it at their local time. Here date and time zone are not required.

My car’s clock only has 1-12 hours no AM/PM.

What I’m trying to say is that your solution should be different depending on what the users of the instrument need for the instrument time and your application for reports.

I hope this makes sense and helps.

The instrument has no time zone setting, just like my wrist watch does not and like my car’s clock does not. The full details of the clock are only used to set file creation date and time for the file system and to tag the starting date and time in the file’s metadata. Buried in the recorded data is the elapsed time in seconds relative to the start of recording.

Jim

Since the instrument does not have a time zone setting - which isn’t uncommon - I believe your app will need to be the one keeping track of the time zone for the instrument. When you read a value from the instrument’s clock, you would supply the expected time zone to the DateTime constructor of your choice, which I suspect will be the separated values constructor. Something like Var InstrumentTime As New DateTime(Year, Month, Day, Hour, Minute, Second, Nanosecond, New TimeZone(InstrumentZoneName)). From that, you can convert into any other time zone with the simpler constructor: Var PacificTime As New DateTime(InstrumentTime.SecondsFrom1970, New TimeZone("America/Los_Angeles")).

This isn’t a simple problem to solve. I’ve dealt with an extremely similar situation before. The meters I needed to pull data from don’t have a time zone, and the client was resistant to adding a setting to the app. They basically wanted magic. There’s no way to solve this without a time zone. Either the app knows the zone the instrument is in, or the instrument provides the zone. It has to come from somewhere. Since the instrument doesn’t know its zone, that really leaves you one option.