0

i have timer. And i got a problem that i have users at few timezones. So one guy see that he has 1 hour left and other one have 6 hours left. I need to make sure that they have all seen 1 time. I got this test code, but if i change time at my Windows, my timer values changed. Thank you for any answer.

using System;

namespace timezone
{
    class Program
    {
        static void Main(string[] args)
        {
            DateTime endDate = DateTime.Parse("2015-09-10 22:20:41");
            TimeSpan difference = endDate - MoscowTime(DateTime.Now);

            Console.WriteLine(difference.Hours + ":" + difference.Minutes + ":" + difference.Seconds);
            Console.ReadLine();
        }

        public static DateTime MoscowTime(DateTime time)
        {
            TimeZone zone = TimeZone.CurrentTimeZone;
            DateTime universal = zone.ToUniversalTime(time);
            return universal.AddHours(3);
        }
    }
}
SLI
  • 713
  • 11
  • 29
  • 2
    Use UTC time to set timer + http://stackoverflow.com/questions/12046398/is-there-an-event-when-windows-system-time-changes-from-an-ntp-time-update to track time changes. – Alexei Levenkov Sep 08 '15 at 20:59
  • 1
    Your problem is not really clear to me. Please provide a few textual examples of users in different time zones, users switching their system clock, etc. as well as the expected outputs. – Christoph Sep 08 '15 at 21:00
  • What is exactly the endDate param? A target time set by the user? – Ismael Sep 08 '15 at 21:02
  • endDate - point when subscription ends – SLI Sep 08 '15 at 21:05
  • "but if i change time at my Windows, my timer values changed" - if you mean changing the time itself and not the Timezone, you can't trust the local Windows Time to get this difference, be aware of that. Take a look at the @AlexeiLevenkov comment to know how to track it. – Ismael Sep 08 '15 at 21:14

2 Answers2

1

Keep your DateTime objects in UTC:

var endDate = new DateTime(2015, 9, 10, 22, 20, 41, DateTimeKind.Utc);
var now = DateTime.UtcNow;

var difference = endDate - now;

If you want to display the dates to the user, convert it to local time, otherwise, keep it in UTC.

If you do not want to trust the local PC's internal clock, you could query a time server for the correct time:

How to Query an NTP Server using C#?

This should give you the now value in UTC, and you can proceed as usual - without relying on the time on the local PC. This obviously requires the PC to be online.

Community
  • 1
  • 1
Troels Larsen
  • 4,462
  • 2
  • 34
  • 54
  • If i change time in Windows than var difference will have other values – SLI Sep 08 '15 at 21:15
  • 1
    Please elaborate on why you need this. If you want to avoid having users 'cheat', you will have to use a different clock than your computers clock. I've updated my answer to reflect this. – Troels Larsen Sep 08 '15 at 21:18
0

If the endDate param is a target date set by the user and it is using the user's local Timezone, you need to ensure that both dates are in the same Timezone.

One way to do it is to put your endDate into the same Timezone as your actual date:

class Program
{
    static void Main(string[] args)
    {
        DateTime endDate = MoscowTime(DateTime.Parse("2015-09-10 22:20:41"));
        TimeSpan difference = endDate - MoscowTime(DateTime.Now);

        Console.WriteLine(difference.Hours + ":" + difference.Minutes + ":" + difference.Seconds);
        Console.ReadLine();
    }

    public static DateTime MoscowTime(DateTime time)
    {
        TimeZone zone = TimeZone.CurrentTimeZone;
        DateTime universal = zone.ToUniversalTime(time);
        return universal.AddHours(3);
    }
}
Ismael
  • 622
  • 6
  • 11