.NET Date and Time Handling

So I started out reading the documentation for .NET date and time handling and I felt I needed a drink. If this is what .NET developers have to deal with, then no wonder so many of them have issues.

It starts with the DateTime structure. It’s purpose is to represent a Date and Time; however this structure possesses both the timestamp and the fact that it’s either a UTC time (i.e. no TZ information whatsoever), or a local time.

Obtaining a value for ‘now’ involves using the static properties DateTime.Now or DateTime.UtcNow. Once you’ve instantiated a DateTime value, you can’t actually change it, so for example doing DateTime.Now.ToUniversalTime() won’t actually change the structure, it returns a new instance of DateTime, which is converted based on the system’s current timezone settings, which means that you can actually get an incorrect value when the time straddles a daylight savings change.

There is an entire Microsoft document on best practices for dealing with DateTime values. It’s a bit tricky. Firstly, try to only deal with dates and times in UTC where possible. There is a major gotcha in the XmlSerializer code in the .NET 1.0/1.1 framework where it always treats the DateTime as localtime, even if you’ve passed in a UtcTime. This seems to have been fixed in later revisions of .NET; so hopefully you won’t encounter it.

Obtaining a DateTime object from a String is a matter of using the DateTime.parse(), you just have to ensure that the parse-string format matches the input string value. The default parse method uses the thread’s current Culture, which means you have to pay attention to things like the pesky mm/dd/yyyy vs dd/mm/yyyy conventions when you’re parsing. If you want to specify the formatting that you’re trying to parse in a manual fashion, you need to use the parse(String stringToParse, IFormatProvider provider) style, which allows you to use another Culture’s parsing format, or define your own.

If you’re planning on performing operations on a DateTime item, such as adding a few hours, days, etc to the original value bear in mind that in order to be safe, you should perform the operation with the timezone set to UTC (which doesn’t have any DST adjustments), and then swap it back to local time. This double trip is intended to avoid errors around ‘spring forward’ and ‘fall back’ times. Even if you don’t think you’re going to encounter those times it’s better safe than sorry.

Because a DateTime only stores a time in either ‘local’ or UTC, when you choose to persist this information you are best off storing the information in UTC and keeping an adjacent element for the timezone, should you actually choose to store it. The simplest way to store it is as the result of the Ticks property. This value is an integer, and is in ten-millionths of a second since 12:00 midnight, January 1, 0001 A.D. (C.E.) in the Gregorian calendar.

The DateTime structure has the ability to extract the Year, Month, Day, Hour, Minute, Second and Milliseconds from the value. It allows the extraction of the ‘Ticks’ value, but this is an absolute value, not an extraction. All these elements are in terms of the Gregorian calendar. It doesn’t matter if your current culture does not use the Gregorian calendar, it always returns the data in terms of the Gregorian calendar. I don’t know the reason for this choice, considering that it understands the current timezone; but it’s most likely due to the culture being a property of the current thread rather than a more ‘systemmy’ property.

If you want to extract based on a different calendar, such as the Persian calendar, you need to extract them via an instance of the calendar. The Persian Calendar is easily instanced from System.Globalization.PersianCalendar, but if you need the calendar for a specific region, you should instantiate a CultureInfo using new System.Globalization.CultureInfo(String CultureCode, bool userOverride), and then extract it’s Calendar property. In this case I can do:

var date = DateTime.utcNow;
CultureInfo cinfo = new System.Globalization.CultureInfo("EN-ie", false); // get the English-speaking, Ireland culture
int year = cinfo.Calendar.GetYear(date);
// This year is based on the calendar from Ireland (Gregorian), but you get the idea as to how to use it for other calendars.

The Calendar class deals with the breaking of a Date & Time into pieces. Those pieces are defined in terms of the calendar – this can be confusing if you’re only used to a single calendar, as many people are. I live in a region that uses the Gregorian calendar exclusively, so I deal with dates and times in those terms. The Gregorian calendar was formalized by Pope Gregory in 1582 (by that calendar’s reckoning), which was, in itself a correction to the Julian calendar. You can, in fact, get dates and times in terms of the Julian calendar, which was off because it insisted on a leap year every 4 years, with no exceptions – bear in mind that the Gregorian calendar has two exceptions to the rule – no leap years on years divisible by 100, but it does have a leap year if it’s also divisible by 400 – so, for example 1900 was not a leap year, but 2000 was a leap year, while 2100 will not be a leap year.

So with the .NET environment we have the DateTime, which represents a point in time, we then have the Calendar, which is a representation of the DateTime in terms of a particular calendar i.e it’s representation in terms of the year, month, day, day of week. There can me more delineations of the date & time – it’s up to the calendar to define them.

There are many ways to make an instance of a DateTime, possibly the simplest of which is to use the Now static property, but you can also construct them explicitly, using a variety of constructors, The simplest is the DateTime(ticks), which makes one in terms of the number of ticks since 0-time. But you can construct them made up of just the year, month and day; combined with an hour, minute and second; or even subsequently combined with a millisecond value. These can be specified as ‘local’ or UTC, and can also be specified in terms of a calendar. Once you’ve constructed the DateTime instance, it will no longer be represented in terms of that calendar, but will be represented in terms of the Gregorian calendar; e.g.

var cal = new System.Globalization.JapaneseCalendar();
DateTime aDateTime = new DateTime(2014, 1, 1, cal);
System.Diagnostics.Debug.Assert(aDateTime.Year == 2014);

This assertion will trigger, because it’s no longer in terms of the Japanese Calendar.

Parsing of DateTime values can be done using DateTime.parse(), which takes a string, and turns it into a DateTime. it uses the current Culture; unless it can be parsed as ISO 8601 – so when I’m here in little old ireland, if I put in a string of 1/2/2015, it tells me February 1, 2015, but if I’m in the US, it represents January 2, 2015. So you have to be careful when parsing DateTime values. This is where the IFormatProvider parameter comes in – this interface is generally not manually created by the user, but is, instead extracted from an instance of a culture e.g.

IFormatProvider if_us = new System.Globalization.CultureInfo("EN-us", false);
IFormatProvider if_ie = new System.Globalization.CultureInfo("EN-ie", false);
DateTime ieDate = DateTime.Parse("1/2/2015", if_ie);
DateTime usDate = DateTime.Parse("1/2/2015", if_us);
System.Diagnostics.Debug.Assert(ieDate.Year == usDate.Year);
System.Diagnostics.Debug.Assert(ieDate.Month != usDate.Month);
System.Diagnostics.Debug.Assert(ieDate.Day != usDate.Day);
System.Diagnostics.Debug.Assert(ieDate.Month == usDate.Day);
System.Diagnostics.Debug.Assert(ieDate.Day == usDate.Month);

None of these assertions trip, because we know/understand how the string is parsed by these cultures.

The next thing you generally need to do is deal with displaying times in different time zones. You already have a DateTime instance, which is either local, or UTC, and you want to turn it into a local time. So what you need is a TimeZoneInfo, and then going back to a DateTime that displays in that format:

TimeZoneInfo irelandtz = TimeZoneInfo.FindSystemTimeZoneById("GMT Standard Time");
TimeZoneInfo newyorktz = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");
var now = DateTime.UtcNow;
DateTime irelandnow = TimeZoneInfo.ConvertTimeFromUtc(now, irelandtz);
DateTime newyorknow = TimeZoneInfo.ConvertTimeFromUtc(now, newyorktz);
Console.WriteLine(" {0} {1}", irelandnow, irelandtz.IsDaylightSavingTime(irelandnow) ? irelandtz.DaylightName : irelandtz.StandardName);
Console.WriteLine(" {0} {1}", newyorknow, newyorktz.IsDaylightSavingTime(newyorknow) ? newyorktz.DaylightName : newyorktz.StandardName);

Now this code is awful, you are not actually picking the timezone by location – it’s by a name of timezone, rather than the location that specifies the timezone – e.g. Europe/Dublin and America/NewYork. There is a much better alternative for dealing with DateTime values, and that’s to use the NodaTime, which gives a little bit better an experience:

Instant now = SystemClock.Instance.Now;
DateTimeZone dublin = DateTimeZoneProviders.Tzdb["Europe/Dublin"];
DateTimeZone newyork = DateTimeZoneProviders.Tzdb["America/New_York"];
Console.WriteLine(new ZonedDateTime(now, dublin).ToString());
//2015-02-07T20:48:20 Europe/Dublin (+00)
Console.WriteLine(new ZonedDateTime(now, newyork).ToString());
//2015-02-07T15:48:20 America/New_York (-05)

Is that a DLL in your pocket…

Shock! Horror! Bug found where Windows applications will open DLLs that are in the current working directory of a process!

Except it’s not a bug. It’s by design, and it’s existed since NT.

Microsoft is being smacked in the head by a required feature of Windows due to the initial weakness of the LoadLibrary call. If you don’t specify a path to the file to load, it uses the standard library search path.

Dear god, you would think that this was news. It is not news, nor has it been since the goddamned operating system shipped. Granted, the issue is severe, but the fact of the matter is if an application is executed using a working directory that isn’t under your control, then what can you do? if there are libraries in the same directory that launched the program that happen to share the name of system libraries then you’re hosed.

Hey, guess what asshole, if you link a linux binary with a search path containing ‘.’, then you get the same problem. It’s just as well that nobody links their binaries with -R. …. eh?

The documentation is blatant in this regard. I’ve known it was a security issue since I first learned of the LoadLibrary call, as any even half decent developer should have known when they started using the damned function.

The rule is simple. Resolve the full path to a library before you load it. Validate that it ‘looks right’ at that point. Then load it.

BTW .init section in .so files – so totally a security hole. You can’t dlopen a file to determine if it’s good without executing the .init code. Game over man, game f**king over!

My .init code does a setenv(“LD_LIBRARY_PATH”, “.” + getenv(“LD_LIBRARY_PATH”)) … now piss off and write secure code for once…

Virtual PC connection to the host while on the road

This advice is for Microsoft Virtual PC. When you use software like VMWare, it automatically allows the host to connect directly to the client using the virtual interfaces that have been created.

Most of the recommendations with regard to connection to/from the Virtual PC client recommend configuring the connection to share/bridge one of the network connections.

All very good and well when you’re on a network. I regularly use the system when I have no network available – i.e. I’m completely disconnected. Most of the connection sensing code for network adaptors prevent you from using it while it’s not active, plus I don’t like having to configure the connection manually and then reconfigure it when I’ve got a real network.

The simple solution is to add a Microsoft Loopback Adaptor to the host machine, then create a second network interface on the Virtual PC that uses this interface. Manually configure the IP addresses to be on the same private network, making sure that you don’t accidentally configure it to use an IP address range that you may end up using for a VPN connection.

  1. Add the Network Adaptor: XP, Vista, Windows 7
  2. Configure the IP address manually. Use a Private Address Range. I chose an IP address of 10.125.1.1 with a netmask of 255.255.255.0 for the host, then chose 10.125.1.2 for the Virtual machine. XP, Vista, Windows 7 – Use the instructions for Vista.
  3. Shutdown the Virtual Machine, Don’t hibernate as you can’t add the second network interface.
  4. Edit the properties of the virtual machine (in the Virtual Machines folder). Either Right Click on the Virtual Machine Icon, or use the Settings Option in the menu bar.
    Settings Option
  5. Configure the network to have 2 interfaces, one of which is linked to the ‘Microsoft Loopback Adaptor’
    Settings Dialog
  6. Boot up the virtual machine, and follow the instructions for manually configuring the IP address of this new network interface.

Direct connections to the IP address of the client virtual machine now work, and you can use it for anything you want.

Following the instructions here, even if they’re confusing, once you add a dword key called ‘*NdisDeviceType’, with a value of 1, you don’t see the connection as an unknown connection; thus enabling sharing and other features in Vista, Win 7.

Programmatically changing environment variables in Windows

It’s not difficult to set environment variable in Windows. System level variables are stored in HKLM/System/CurrentControlSet/Control/Session Manager/Environment. User level variables are stored in HKCU/Environment. They are either REG_SZ or REG_EXPAND_SZ variables. REG_EXPAND_SZ values use other environment variables to get their ultimate value, while REG_SZ values are considered ‘final destination’ variables.

The issue arises when you programmatically change the value and want it reflected in new programs that are launched. You make your changes in the registry, but none of the newly launches applications notice the change. You need to inform all the running applications that the settings have been changed. To do this you send a WM_SETTINGCHANGE message to all the running applications.

The logic is to issue a SendMessage(HWND_BROADCAST, WM_SETTINGCHANGE, 0, (LPARAM)"Environment"). As the meerkat in the advertisement says ‘Seemples’. Unfortunately, I have a couple of applications with badly written message processing loops which don’t defer to DefWndProc if they don’t handle the message, which causes this function to hang.

The more sensible logic is to use a SendMessageTimeout call, which has 2 extra parameters, one of which is a flag and the other is a timeout in milliseconds. The timeout is a maximum per window, which means that if there are 10 windows causing timeouts and you’re issuing it with a 1000 milli-second (1 second) timeout, then you will be stalled for 10 seconds. You have been warned. Most applications should respond in < 100 milli-seconds, and typically there are only a few badly behaved applications.

This brings us to the code. It’s short, and it’s C and it doesn’t do anything fancy at all. Compiled using MinGW as gcc -mwindows settings.c -o settings.exe

#include <windows.h>

int APIENTRY WinMain(HINSTANCE hInstance,
  HINSTANCE hPrevInstance,
  LPSTR lpCmdLine,
  int nCmdShow)
{
    DWORD output;
    SendMessageTimeout(HWND_BROADCAST, WM_SETTINGCHANGE, 0,
      (LPARAM)"Environment", SMTO_BLOCK, 100, &output);
    return (0);
}

Set a variable in the registry. Pop up a cmd window and issue a set command and the change is not reflected in the window. Close the window, run the settings program compiled above, then launch another cmd window and it will now reflect the change to the environment you made in the registry.

The message causes Explorer to re-read the environment, which is why newly launched programs see the changes. You are launching your applications from explorer (the start menu, icons on the desktop, the run menu) for the most part.

Important! Must install! You will die without it!

CreativeWhine Oh get over yourself! I do not need to install the music management software on my computer and not having it installed is not the end of the world. It’s almost as bad as the apple updater suggesting you install Safari. Mind you, it’s nowhere near as annoying about it, and it doesn’t suggest that the world will end if you don’t download it (but, you know, it just might…)

I reboot and get an ’emergency security update’ from Flash

Flash Update Message Apparently, it needed to install a security update. I don’t believe I’m using any flash applications that would keep the player in use, so why the pathetic dialog on the left after I installed it? This is one of those cases where pushing through the update makes more sense. As it is this only tells me that I need to reboot my computer to be safe from ‘flash viruses‘.
Is it that the flash component is so embedded in the operating system that updating it requires a reboot? If that’s the case then why? it’s only a little thing for displaying animations; not the end of the fricking world.

First week into the use of Firefox3

It’s great. simply prettier and a lot more usable than Firefox 2. The awesome bar (the address bar) kicks ass. Much easier to use than the previous one. Bookmark management has been improved. The look and feel is nicer. I even ‘kind of‘ prefer the subtle dialog box improvement which turns up at the top of the form, which is like a wide series of websites that perform the same thing themselves.
This definitely has replaced my web browsers in Windows and Linux. There’s a very high chance that it will replace Safari on the Mac. The only niggle I have is that it doesn’t store your passwords in the Mac keychain, which I still feel is the better place to have them.
Damn the electric fence…

vmware – moving a network address

Every time you reinstall vmware it seems to recreate your network interfaces, and at the same time reassigns the ip addresses that you had set up. If you want to move them then you need to edit a file and a couple of registry entries.
The first file is %APPDATA%\VMware\vmnetdhcp.conf. On XP it’s normally C:\Documents and Settings\All Users\Application Data, Under Vista that’s C:\ProgramData. Note, however that when UAC is enabled, this folder experiences redirection on write by unprivileged users, so editing this file as an ordinary user will have no effect, so make sure that you use a privileged editor when altering this file.
The content you want to change are the Subnet and Range entries to match your original subnet entries you had. You can also put in entries for the domain-name and router. When you add this information it gives you the ability to mark a the subnet as identified under Vista, so you can be in an identified network, and thus be discoverable. Please note that doing this and then putting an insecure OS on the client vm is your own fault.
The other entries that need to be altered are in the registry. The first one is HKLM\Software\VMware, Inc.\VMnetLib\VMnetConfig\vmnet? entries – the IPSubnetAddress entry needs to be changed to match the entries that you set in the .conf file. The next one is a little bit tricky – it’s HKLM\SYSTEM\CurrentControlSet\Services\VMnetDHCP\Parameters\VirtualEthernetSegments\?, the value is HostIpAddress – and it needs to be mapped. The value is a endian-reversed representation of your address so if your ip address is 192.168.22.1 the value would be 0x0116A8C0, C0==192, a8==168, 16=22, 01=01. Use Calc to get the values that you should put in there.
Restart the service “vmware dhcp service”, and then you should be OK.

Oi, apple stop installing the ‘update service’

For some reason even though I explicitly un-check the ‘apple software update’ option when installing either itunes or the bonjour service I am unsurprised to find that it has been installed.
Along with the quicktime icon in the notification area. Please respect my wishes to keep my notification area clear. It’s already cluttered with the detritus of outlook, pidgin, vmware, creative X-fi, hotsync, sync manager, bluetooth, quickset, virtual daemon manager, the power status, network status, volume and the sidebar. At least I can switch off clock, volume, network and power if I so choose, and they respect my authoritay.

Vista, unidentified networks and vmware

The network interfaces that get configured by vmware always fall into the ‘unidentified realm’. The reason seems to be tied to the lack of a router or default gateway entry for the address.
So we cheat, and add in a router entry for the networks that is the same as the IP address of the connection and bingo, you get the option to put it into another network and give it a label! So I put both the VMware network interfaces and the Microsoft loopback interface into a group called ‘local only’, and providing I don’t use any grotty windows virtual machines, it should service me well. Of course, this is all purely academic for those who don’t use vista