Ok, a couple things still confuse me, and I think there is still something wrong with GetTimeZoneOffsetAt.
1. TimezoneOffset is a Double, GetTimeZoneOffsetAt returns a Double, SetTimezone wants an Int. As far as I know offsets and DST shifts are all Ints, so where do the Doubles come in? TimezoneOffset is also Read Only, so the only way to set it is with an Int.
2. I agree Ticks are stored as GMT/UTC and the default TimezoneOffset appears to be the same as what GetTimeZoneOffsetAt returns which is the Shift + DST. This is where things start to differ though...how is GetTimeZoneOffsetAt figuring its value? It appears to be just going directly off of the TimezoneOffset number. I see nowhere to specify a Timezone for areas like Arizona and others that don't perform DST. With this in mind I was expecting GetTimeZoneOffsetAt to read from the Device Timezone instead of the Application offset in DateTime, but it is not. (I also tried setting my Timezone in Android to Arizona and the Datetime object performs an invalid DST shift when I change the date on the device- Both the default TimezoneOffset and what GetTimeZoneOffsetAt returns)
I have an application where I want to store GMT Time in the database, so I do a DateTime.SetTimeZone(0) before writing to text to the database (This goes into MySql later and ticks have limitations similar to Y2K until everything goes 64bit, so I don't store ticks). I then do a DateTime.SetTimeZone(DateTime.GetTimeZoneOffsetAt(DateTime.Now)) that I had expected to reset it back to the correct offset, but it sets it to 0 like it is getting the offset of GMT and also doesn't include DST.
This may work for some areas, but in reality there is no true way of returning the DateTime object's Timezone to the device's after it is changed and it is calculating DST shifts incorrect, so in some cases it may not even match the devices offset.
I think if I had some Reflection code to just get the device's current offset (That may or may not included DST) then I can make my code work since all I care about is what 0/GMT looks like and what the device's current is to show it to the user right. For the object itself to work right GetTimeZoneOffsetAt will most likely need to do the same thing instead of what it is currently doing as it can't accurately figure the offset by number only.