Get the next immediate Time from a list of date time in dart - flutter

If I have a list of DateTime =
[
2021-08-17 11:00:00.000000,
2021-08-17 11:30:00.000000,
2021-08-17 12:00:00.000000,
2021-08-17 12:30:00.000000,
2021-08-17 13:00:00.000000,
]
How can I find the immediate next TIME using DateTime.now()?
ONLY TIME.
If DateTime.now() returns 2021-08-17 11:25:00.000000 I need to return 5 minutes
**CONTEXT: **
My application needs to save the DateTime for another work so I cannot just save the Time. The above mentioned list of DateTimes is saved under the title: Sunday. Checking if today is Sunday or not is quite easy but I need some sort of mechanism for getting the difference with next datetime but I only need the Time difference and not the date

Assuming that your List<DateTime> is sorted in order of earliest to latest, a straightforward, brute-force approach is to just iterate over your List<DateTime> and stop when you find one that is at or after the specified DateTime:
/// Returns the [Duration] to the next [DateTime] from [validTimes] that occurs at
/// or after [now].
///
/// Returns `null` if there is no [DateTime] at or after [now].
///
/// [validTimes] must be already sorted in order of earliest to latest.
Duration? timeToNext(List<DateTime> validTimes, DateTime now) {
for (var time in validTimes) {
if (time.compareTo(now) >= 0) {
return time.difference(now);
}
}
return null;
}
void main() {
var times = [
DateTime(2021, 08, 17, 11, 00),
DateTime(2021, 08, 17, 11, 30),
DateTime(2021, 08, 17, 12, 00),
DateTime(2021, 08, 17, 12, 30),
DateTime(2021, 08, 17, 13, 00),
];
var now = DateTime(2021, 08, 17, 11, 25);
var duration = timeToNext(times, now);
print(duration); // Prints: 0:05:00.000000
}
If your List<DateTime> is very large, then you could use lowerBound from package:collection:
import 'package:collection/collection.dart';
Duration? timeToNext(List<DateTime> validTimes, DateTime now) {
var i = lowerBound(validTimes, now);
if (i == validTimes.length) {
return null;
}
return validTimes[i].difference(now);
}

If i understood correctly,
the difference between DateTimes is pretty easy using difference method for the DateTime class look that in action:
int returnDiference(DateTime dateTime1, DateTime dateTime2) {
final int diference = dateTime1.difference(dateTime2).inSeconds;
return diference;
}
enter image description here
I hope that will be useful for you.

Related

How to get DateTime with zeroed time in Flutter

I'm new to Flutter and I'm trying to output the start of the current day in UTC format.
I use Flutter 3.3.7 and Dart SDK 2.18.4.
First, I take the current date.
DateTime dt = DateTime.now();
Next, I use extension for the DateTime class, which I implemented myself.
extension DateTimeFromTimeOfDay on DateTime {
DateTime appliedFromTimeOfDay(TimeOfDay timeOfDay) {
return DateTime(year, month, day, timeOfDay.hour, timeOfDay.minute);
}
}
It outputs the same date, only with the time that I pass it via TimeOfDay class(In this case 00:00).
dt = dt.appliedFromTimeOfDay(const TimeOfDay(hour: 0, minute: 0));
print(dt.toUtc()); //2022-11-08 21:00:00.000Z
But when I run this code, it outputs a date with a non-zero time.
I also tried adding the toUtc() method to the extension.
extension DateTimeFromTimeOfDay on DateTime {
DateTime appliedFromTimeOfDay(TimeOfDay timeOfDay) {
return DateTime(year, month, day, timeOfDay.hour, timeOfDay.minute).toUtc();
}
}
That didn't work either.
How can I get the DateTime in UTC format with zeroed time of day? For example,
2022-11-08 00:00:00.000Z
DateTime has a utc constructor that allows you to do this.
extension DateTimeFromTimeOfDay on DateTime {
DateTime appliedFromTimeOfDay(TimeOfDay timeOfDay) {
return DateTime.utc(year, month, day, timeOfDay.hour, timeOfDay.minute);
}
}
DateTime today = DateTime.now()
.appliedFromTimeOfDay(const TimeOfDay(hour: 0, minute: 0)); // output: 2022-11-09 00:00:00.000Z (note the Z which indicate UTC)
Try it with this extension method
extension DateTimeExtension on DateTime {
DateTime getDateOnly() {
return DateTime(this.year, this.month, this.day);
}
}

How to sort TimeOfDay list from earliest to latest time?

I need to display a schedule for users that displays times from earliest to latest time. I have a TimeOfDay list containing times and need it to be sorted from earliest to latest time. I made a function for it, but keep getting _TypeError (type 'TimeOfDay' is not a subtype of type 'String') when I run my code. Since I utilize the function inside a Column in my Widget build code block, I think it has to return a widget. Please let me know how I can resolve this error and efficiently sort my list through a function. The code for my function is below, any help would be appreciated!
listOrder(l) {
l.sort((a,b) => DateTime.parse(a).compareTo(DateTime.parse(b)));
return Text('Done!');
}
DateTime.parse expects a String input, not a TimeOfDay instance.
If you want to sort a List<TimeOfDay>, you need to provide a comparison function that compares TimeOfDay instances:
int compareTimeOfDay(TimeOfDay time1, TimeOfDay time2) {
var totalMinutes1 = time1.hour * 60 + time1.minute;
var totalMinutes2 = time2.hour * 60 + time2.minute;
return totalMinutes1.compareTo(totalMinutes2);
}
void main() {
var list = [
TimeOfDay(hour: 12, minute: 59),
TimeOfDay(hour: 2, minute: 3),
TimeOfDay(hour: 22, minute: 10),
TimeOfDay(hour: 9, minute: 30),
];
list.sort(compareTimeOfDay);
print(list);
}
i think you are missing return value form sort method. since you are using curly brackets,
here i try on dartpad is working fine
void main() {
List date = ['2022-02-02','2022-02-15','2022-02-01'];
date.sort((a,b) => DateTime.parse(a).compareTo(DateTime.parse(b)));
print(date); //result : [2022-02-01, 2022-02-02, 2022-02-15]
}
if you have 1 argument, you can simplify with arrow => , but if you have more than 1, use brackets {}
l.sort((a,b){
return DateTime.parse(a).compareTo(DateTime.parse(b)); // see i add a return syntax
});

Flutter how to subtract time from other time

I have 2 times which I need to do subtract and I am almost close but there is one big issue
I have 2 times in string-like 10:00AM and 10:00PM
And my code is this
var df = DateFormat("hh:mm");
var durationStart = DateFormat('HH:mm').format(df.parse(10:00AM));
var durationEnd = DateFormat('HH:mm').format(df.parse(10:00PM));
print('durationStart ${durationStart}');
print('durationEnd ${durationEnd}');
var Startparts = durationStart.split(':');
var startDurationSet = Duration(hours: int.parse(Startparts[0].trim()), minutes: int.parse(Startparts[1].trim()));
var Endparts = durationEnd.split(':');
var endDurationSet = Duration(hours: int.parse(Endparts[0].trim()), minutes: int.parse(Endparts[1].trim()));
print('startDurationSet ${startDurationSet}');
var result = Duration(hours: int.parse(Endparts[0].trim()) - int.parse(Startparts[0].trim()) , minutes: int.parse(Startparts[1].trim()) - int.parse(Endparts[1].trim()));
print('result ${result.toString().replaceAll('-', '')}');
So I have 2 times one is startTime and one is End time. I simply need a difference between hours. for example, I have 10:00Am and 01:00PM i need 3hours but it's showing 9hours. But what I am receiving is if I have 10:00AM and 10:00pm it's showing 0 hours but its needs to show 12. Same
It is easy if you can get your start and end date in DateTime properly
Hint, I use "hh:mma" since that is your original format => "10:00AM"
If I use "HH:mm" like you do, i'll always get the same time since it doesn't parse the AM/PM after the 10:00
// Get your time in term of date time
DateTime startDate = DateFormat("hh:mma").parse("10:00AM");
DateTime endDate = DateFormat("hh:mma").parse("10:00PM");
// Get the Duration using the diferrence method
Duration dif = endDate.difference(startDate);
// Print the result in any format you want
print(dif.toString(); // 12:00:00.000000
print(dif.inHours); // 12
Are you looking for something like this?
TimeOfDay _calcTimeOfDay(int hour, int minute) {
if (minute > 60) {
minute = (minute % 60);
hour += 1;
}
return TimeOfDay(hour: hour, minute: minute);
}
The problem is if you have hour=24 and minute=75 then the hour would be 25, which is not a valid hour.
Not sure I fully understand the question, maybe if you can provide more info.
What you need to add on your DateFormat is the code for am/pm marker: a. Using either format hh:mma or h:ma should work.
You can then use DateTime.difference() to calculate the time variance from durationStart and durationEnd. Here's a sample that you can run on DartPad.
import 'package:intl/intl.dart';
void main() {
/// Set the format that of the Date/Time that like to parse
/// h - 12h in am/pm
/// m - minute in hour
/// a - am/pm marker
/// See more format here: https://pub.dev/documentation/intl/latest/intl/DateFormat-class.html
var dateFormat = DateFormat('h:ma');
DateTime durationStart = dateFormat.parse('10:00AM');
DateTime durationEnd = dateFormat.parse('10:00PM');
print('durationStart: $durationStart');
print('durationEnd: $durationEnd');
/// Fetch the difference using DateTime.difference()
/// https://api.flutter.dev/flutter/dart-core/DateTime/difference.html
print('difference: ${durationEnd.difference(durationStart).inHours}');
}
Use package
intl: ^0.17.0
import 'package:intl/intl.dart';
var dateFormat = DateFormat('h:ma');
DateTime durationStart = dateFormat.parse('10:00AM');
DateTime durationEnd = dateFormat.parse('1:00PM');
print('durationStart: $durationStart');
print('durationEnd: $durationEnd');
var differenceInHours = durationEnd.difference(durationStart).inHours;
print('difference: $differenceInHours hours');
I have created one class for you:
import 'package:intl/intl.dart';
class DateUtils {
static String getTimeDifference(String startTime, String endTime){
/// Set the format that of the Date/Time that like to parse
/// h - 12h in am/pm
/// m - minute in hour
/// a - am/pm marker
/// See more format here: https://pub.dev/documentation/intl/latest/intl/DateFormat-class.html
var dateFormat = DateFormat('h:ma');
DateTime durationStart = dateFormat.parse(startTime);
DateTime durationEnd = dateFormat.parse(endTime);
return '${durationEnd.difference(durationStart).inHours} hours';
}
}
How you can use:
void main() {
print("10:00PM, 10:30PM => " + DateUtils.getTimeDifference("10:00PM", "10:30PM"));
print("12:00AM, 04:00AM => " + DateUtils.getTimeDifference("12:00AM", "04:00AM"));
print("01:00AM, 03:00AM => " + DateUtils.getTimeDifference("01:00AM", "03:00AM"));
print("12:00AM, 06:00PM => " + DateUtils.getTimeDifference("12:00AM", "06:00PM"));
print("04:00PM, 03:00PM => " + DateUtils.getTimeDifference("04:00PM", "03:00PM"));
}
Output:
10:00PM, 10:30PM => 0 hours
12:00AM, 04:00AM => 4 hours
01:00AM, 03:00AM => 2 hours
12:00AM, 06:00PM => 18 hours
04:00PM, 03:00PM => -1 hours
Hope it will be helpful.

Getting just the year, month, and date in flutter? [duplicate]

All I can see in the documentation is DateTime.now() but it returns the Timespan also, and I need just the date.
Create a new date from now with only the parts you need:
DateTime now = new DateTime.now();
DateTime date = new DateTime(now.year, now.month, now.day);
Hint: "new" is optional in Dart since quite a while
If you want only the date without the timestamp. You can take the help of intl package.
main() {
var now = new DateTime.now();
var formatter = new DateFormat('yyyy-MM-dd');
String formattedDate = formatter.format(now);
print(formattedDate); // 2016-01-25
}
This requires the intl package:
dependencies:
intl: ^0.16.1
And finally import:
import 'package:intl/intl.dart';
You can get the current date using the DateTime class and format the Date using the DateFormat. The DateFormat class requires you to import the intl package so
add to pubspec.yaml
dependencies:
intl: ^0.17.0
and import
import 'package:intl/intl.dart';
and then format using
final now = new DateTime.now();
String formatter = DateFormat('yMd').format(now);// 28/03/2020
In case you are wondering How do you remember the date format(DateFormat('yMd'))? Then Flutter Docs is the answer
The DateFormat class allows the user to choose from a set of standard date time formats as well as specify a customized pattern under certain locales.
The below formats are taken directly from the docs
/// Examples Using the US Locale:
/// Pattern Result
/// ---------------- -------
new DateFormat.yMd() -> 7/10/1996
new DateFormat('yMd') -> 7/10/1996
new DateFormat.yMMMMd('en_US') -> July 10, 1996
new DateFormat.jm() -> 5:08 PM
new DateFormat.yMd().add_jm() -> 7/10/1996 5:08 PM
new DateFormat.Hm() -> 17:08 // force 24 hour time
ICU Name Skeleton
-------- --------
DAY d
ABBR_WEEKDAY E
WEEKDAY EEEE
ABBR_STANDALONE_MONTH LLL
STANDALONE_MONTH LLLL
NUM_MONTH M
NUM_MONTH_DAY Md
NUM_MONTH_WEEKDAY_DAY MEd
ABBR_MONTH MMM
ABBR_MONTH_DAY MMMd
ABBR_MONTH_WEEKDAY_DAY MMMEd
MONTH MMMM
MONTH_DAY MMMMd
MONTH_WEEKDAY_DAY MMMMEEEEd
ABBR_QUARTER QQQ
QUARTER QQQQ
YEAR y
YEAR_NUM_MONTH yM
YEAR_NUM_MONTH_DAY yMd
YEAR_NUM_MONTH_WEEKDAY_DAY yMEd
YEAR_ABBR_MONTH yMMM
YEAR_ABBR_MONTH_DAY yMMMd
YEAR_ABBR_MONTH_WEEKDAY_DAY yMMMEd
YEAR_MONTH yMMMM
YEAR_MONTH_DAY yMMMMd
YEAR_MONTH_WEEKDAY_DAY yMMMMEEEEd
YEAR_ABBR_QUARTER yQQQ
YEAR_QUARTER yQQQQ
HOUR24 H
HOUR24_MINUTE Hm
HOUR24_MINUTE_SECOND Hms
HOUR j
HOUR_MINUTE jm
HOUR_MINUTE_SECOND jms
HOUR_MINUTE_GENERIC_TZ jmv
HOUR_MINUTE_TZ jmz
HOUR_GENERIC_TZ jv
HOUR_TZ jz
MINUTE m
MINUTE_SECOND ms
SECOND s
Hope this helps you to get Date in any format.
this without using any package (it will convert to string)
DateTime dateToday =new DateTime.now();
String date = dateToday.toString().substring(0,10);
print(date); // 2021-06-24
With dart extension
extension MyDateExtension on DateTime {
DateTime getDateOnly(){
return DateTime(this.year, this.month, this.day);
}
}
Usage:
DateTime now = DateTime.now(); // 30/09/2021 15:54:30
DateTime dateOnly = now.getDateOnly(); // 30/09/2021
use this
import 'package:intl/intl.dart';
getCurrentDate() {
return DateFormat('yyyy-MM-dd – kk:mm').format(DateTime.now());
}
If you just need to print the year from a Timespan you can simply do:
DateTime nowDate = DateTime.now();
int currYear = nowDate.year;
print(currYear.toString());
There's no class in the core libraries to model a date w/o time. You have to use new DateTime.now().
Be aware that the date depends on the timezone: 2016-01-20 02:00:00 in Paris is the same instant as 2016-01-19 17:00:00 in Seattle but the day is not the same.
If you prefer a more concise and single line format, based on Günter Zöchbauer's answer, you can also write:
DateTime dateToday = DateTime(DateTime.now().year, DateTime.now().month, DateTime.now().day) ;
Though, it'll make 3 calls to DateTime.now(), the extra variable won't be required, especially if using with Dart ternary operator or inside Flutter UI code block.
In case someone need the simplest way to format date/time in flutter, no plugin needed:
var MONTHS = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
String formattedDateTime() {
DateTime now = new DateTime.now();
return now.day.toString()+" "+MONTHS[now.month-1]+" "+now.year.toString()+" "+now.hour.toString()+":"+now.minute.toString()+":"+now.second.toString();
}
example result: 1 Jan 2020 07:30:45
Change:
MONTHS array to show the month in any language
the return string as needed: to show date only, time only, or date in
different format (dd/mm/yyyy, dd-mm-yyyy, mm/dd/yyyy, etc.)
If you want device's current date just use this
DateTime internetTime = DateTime.now();
DateTime date = new DateTime(now.year, now.month, now.day);
Or if u want internet time, then use below plugin
ntp: ^2.0.0
import 'package:ntp/ntp.dart';
final int offset = await NTP.getNtpOffset(
localTime: DateTime.now(), lookUpAddress: "time.google.com");
DateTime internetTime = DateTime.now().add(Duration(milliseconds: offset));
DateTime internetTime = new DateTime(now.year, now.month, now.day);
Or if you need internet time but you don't want to use plugin then use api call
"http://worldtimeapi.org/api/timezone/Asia/Kolkata"
{
"abbreviation": "IST",
"client_ip": "136.232.222.86",
"datetime": "2022-09-30T17:13:10.299478+05:30",
"day_of_week": 5,
"day_of_year": 273,
"dst": false,
"dst_from": null,
"dst_offset": 0,
"dst_until": null,
"raw_offset": 19800,
"timezone": "Asia/Kolkata",
"unixtime": 1664538190,
"utc_datetime": "2022-09-30T11:43:10.299478+00:00",
"utc_offset": "+05:30",
"week_number": 39
}
first go to pub.dev and get the intl package and add it to your project.
DateFormat.yMMMMd().format(the date you want to render . but must have the type DateTime)
You can use the day in DateTime.now()

DateTimeOffset adding TimeSpan returns invalid UTC offset for its TimeZoneInfo

I am in the process of building a temporal expression library that must be properly globalized and therefore work in all available Time Zones.
Now I seem to be stuck as I'm not sure how to retrieve adjusted dates from DateTimeOffset objects in the correct Daylight Savings Time (DST) when the transition boundary is crossed using any variety of .Add to move days, hours, etc.
Interestingly, I figured out a work around for the local system's Time Zone but haven't found any way to apply the same strategy to any arbitrary Time Zone.
I was able to find a snippet (didn't keep source, sorry!) which tries to reverse lookup the Time Zone Info by offset but as there are multiple potential results, each of which likely have different DST rules that will not work. (There may be some optimizations available but the base premis is flawed I think)
public TimeZoneInfo GetTimeZoneInfo(DateTimeOffset Value)
{
// Search available sytem time zones for a matching one
foreach (var tzi in TimeZoneInfo.GetSystemTimeZones())
{
// Compare value offset with time zone offset
if (tzi.GetUtcOffset(Value).Equals(Value.Offset))
{
return tzi;
}
}
}
This stuff can be a bit tedious to prove out so I've extracted the core issue into a couple methods and unit tests which will hopefully demonstrate the issue I'm facing.
public DateTimeOffset GetNextDay_Wrong(DateTimeOffset FromDateTimeOffset)
{
// Cannot create a new DateTimeOffset using simply the supplied value's UtcOffset
// because in PST, for example, it could be -7 or -8 depending on DST
return new DateTimeOffset(FromDateTimeOffset.Date.AddDays(1), FromDateTimeOffset.Offset);
}
[TestMethod]
public void GetNextDay_WrongTest()
{
var tz = TimeZoneInfo.FindSystemTimeZoneById("Pacific Standard Time");
var workingDate = new DateTime(2009, 11, 2, 0, 0, 0);
var failingDate = new DateTime(2009, 11, 1, 0, 0, 0);
var workingDate_tz = new DateTimeOffset(workingDate, tz.GetUtcOffset(workingDate));
var failingDate_tz = new DateTimeOffset(failingDate, tz.GetUtcOffset(failingDate));
var actual_workingDate_tz = GetNextDay_Wrong(workingDate_tz);
var actual_failingDate_tz = GetNextDay_Wrong(failingDate_tz);
var expected_workingDate = new DateTime(2009, 11, 3, 0, 0, 0);
var expected_failingDate = new DateTime(2009, 11, 2, 0, 0, 0);
var expected_workingDate_tz = new DateTimeOffset(expected_workingDate, tz.GetUtcOffset(expected_workingDate));
var expected_failingDate_tz = new DateTimeOffset(expected_failingDate, tz.GetUtcOffset(expected_failingDate));
Assert.AreEqual(expected_workingDate_tz, actual_workingDate_tz, "Should have found the following day's midnight");
Assert.AreEqual(expected_failingDate_tz, actual_failingDate_tz, "Failing date does not have the correct offset for it's DST");
}
public DateTimeOffset GetNextDay_LooksRight(DateTimeOffset FromDateTimeOffset)
{
// Because we cannot create a new DateTimeOffset we simply adjust the one provided!
var temp = FromDateTimeOffset;
// Move back to midnight of the current day
temp = temp.Subtract(new TimeSpan(temp.Hour, temp.Minute, temp.Second));
// Now move to the next day
temp = temp.AddDays(1);
// Let the DateTimeOffset class do it's magic
temp = temp.ToLocalTime();
// Check if the time zone has changed
if (FromDateTimeOffset.Offset != temp.Offset)
{
// Calculate the change amount (could be 30 mins or even stranger)
var delta = FromDateTimeOffset.Offset - temp.Offset;
// Adjust the temp value by the delta
temp = temp.Add(delta);
}
return temp.ToLocalTime();
}
[TestMethod]
public void GetNextDay_LooksRightTest()
{
// Everything is looking good and the test passes now, so we're home free yeah?
// { To work this needs to match your system's configured Local Time Zone, I'm in PST }
var tz = TimeZoneInfo.FindSystemTimeZoneById("Pacific Standard Time");
var workingDate = new DateTime(2009, 11, 2, 0, 0, 0);
var failingDate = new DateTime(2009, 11, 1, 0, 0, 0);
var workingDate_tz = new DateTimeOffset(workingDate, tz.GetUtcOffset(workingDate));
var failingDate_tz = new DateTimeOffset(failingDate, tz.GetUtcOffset(failingDate));
var actual_workingDate_tz = GetNextDay_LooksRight(workingDate_tz);
var actual_failingDate_tz = GetNextDay_LooksRight(failingDate_tz);
var expected_workingDate = new DateTime(2009, 11, 3, 0, 0, 0);
var expected_failingDate = new DateTime(2009, 11, 2, 0, 0, 0);
var expected_workingDate_tz = new DateTimeOffset(expected_workingDate, tz.GetUtcOffset(expected_workingDate));
var expected_failingDate_tz = new DateTimeOffset(expected_failingDate, tz.GetUtcOffset(expected_failingDate));
Assert.AreEqual(expected_workingDate_tz, actual_workingDate_tz, "Should have found the following day's midnight");
Assert.AreEqual(expected_failingDate_tz, actual_failingDate_tz, "Failing date does not have the correct offset for it's DST");
}
[TestMethod]
public void GetNextDay_LooksRight_FAILTest()
{
// Here is where the frustrating part is... aparantly the "magic" that DateTimeOffset provides only works for your systems Local Time Zone...
// { To properly fail this cannot match your system's configured Local Time Zone, I'm in PST so I use EST }
var tz = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");
var workingDate = new DateTime(2009, 11, 2, 0, 0, 0);
var failingDate = new DateTime(2009, 11, 1, 0, 0, 0);
var workingDate_tz = new DateTimeOffset(workingDate, tz.GetUtcOffset(workingDate));
var failingDate_tz = new DateTimeOffset(failingDate, tz.GetUtcOffset(failingDate));
var actual_workingDate_tz = GetNextDay_LooksRight(workingDate_tz);
var actual_failingDate_tz = GetNextDay_LooksRight(failingDate_tz);
var expected_workingDate = new DateTime(2009, 11, 3, 0, 0, 0);
var expected_failingDate = new DateTime(2009, 11, 2, 0, 0, 0);
var expected_workingDate_tz = new DateTimeOffset(expected_workingDate, tz.GetUtcOffset(expected_workingDate));
var expected_failingDate_tz = new DateTimeOffset(expected_failingDate, tz.GetUtcOffset(expected_failingDate));
Assert.AreEqual(expected_workingDate_tz, actual_workingDate_tz, "Should have found the following day's midnight");
Assert.AreEqual(expected_failingDate_tz, actual_failingDate_tz, "Failing date does not have the correct offset for it's DST");
}
The underlying issue with this case is that there is not enough information to perform the appropriate Time Zone conversions. Simple offset is not specific enough to infer the Time Zone because for a given offset at a specific moment there can be multiple potential Time Zones. Because the DateTimeOffset object does not capture and maintain the information about the Time Zone it was created with it must be the responsibility of something external to that class to maintain this relationship.
The thing that threw me off the scent was the call ToLocalTime() which I later realized was in fact introducing an implied TimeZoneInfo into the calculation, that of the configured local time for the machine and I believe that internally the DateTimeOffset must be converting to UTC by simply removing the configured offset and then creating a new DateTimeOffset class using the constructor taking DateTime [in UTC] and TimeZoneInfo [from local system] to produce the correct dst aware resulting date.
Given this limitation I no longer see any value in the DateTimeOffset class over the equally accurate and more valuable combination of DateTime and TimeZoneInfo.