Search code examples
c#datetimemonolog4netutc

DateTime differences between Windows and Mono, and log4net remote appender


I have a program running on a Linux box under Mono 2.10.9. It logs to a program on a Windows 7 box using log4net. My Linux system clock is set to local time, as well as my Windows machine. Executing the following yields slightly different results on each machine:

DateTime now = DateTime.Now;
Console.WriteLine(String.Format("{0} - Kind {1}", now, now.Kind));

On Windows, I get

5/28/2013 8:39:09 PM - Kind local

and on Linux I get

0/735016/0001 8:39:45 PM - Kind local

It appears the conversion is corrupted in Mono, but that's another problem for another day.

In the LoggingEvent objects I receive from the Linux machine, the TimeStamp field actually contains the time in UTC, not local. However, the TimeStamp.Kind property is Local!

This is causing me problems because the log events that originate on Windows are really local, while the log events from Mono are UTC, and I can't tell the difference with Kind, and it looks kind of funny to have log messages that were created moments apart look like they are 5 hours apart.

What can I do to fix this?


Solution

  • Best practice would be to always record log times as UTC:

    DateTime now = DateTime.UtcNow;
    

    This avoids several problems:

    • Gaps when Daylight Saving Time starts
    • Duplication / Ambiguity when Daylight Saving Time stops
    • Log files from different machines not aligning due to time zone settings

    Additionally, if these are servers you are talking about, you should also set the time zone of the machine to UTC. That way, other logs on the system will also match up at the same times, even if they are set to record local values.

    Also, be aware that Windows wants the computer bios to be set to local time, while Linux wants it at UTC. This can cause some interesting behaviors, especially with virtual machines, if multiple VMs are running with different operating systems or if host and guest OS are different. Setting the local time zone to UTC avoids this.

    Regarding the strange output of DateTime.ToString() in Mono - are you by chance running on a Raspberry Pi? This is a known bug. See this answer and the issue linked from there.

    I am not sure why you are getting UTC values instead of local values from Log4Net's LoggingEvent.TimeStamp, since these docs say it is local. However, it is possible you are using an appender that sends the UTC timestamp instead. In the FAQ, there is a question that talks about UTC transmitted by a RemotingAppender. You might be doing something similar. I don't know for sure, since you didn't show that part of your code.