Pergunta

Eu tenho um cenário onde eu tenho um offset (em minutos) fuso horário e necessidade de determinar o fuso horário para ele. Eu sei que todos os dados não está disponível (por exemplo, pode haver vários fusos horários com um deslocamento de -240 minutos), mas uma "melhor estimativa" é aceitável.

A minha primeira passagem ficou assim:

foreach (var info in TimeZoneInfo.GetSystemTimeZones())
{
    if (info.BaseUtcOffset.TotalMinutes == timezoneOffset)
    {
         // do something here if this is a valid timezone
    }
}

Este sorta funciona, mas eu preciso para conta para horário de verão que está me jogando fora um pouco. Eu adicionei este terrível corte:

foreach (var info in TimeZoneInfo.GetSystemTimeZones())
{
    var extra = info.IsDaylightSavingTime(DateTime.Now) ? 60 : 0;
    if (info.BaseUtcOffset.TotalMinutes + extra == timezoneOffset)
    {
         // do something here if this is a valid timezone
    }
}

Isso funciona "bem o suficiente" em que eu possa mostrar ao usuário o tempo correto para eles quando o horário de verão não está em vigor e estou cerca de 70% correta durante DST. Ainda assim ... isso é algum código terrível aos meus globos oculares.

Existe uma maneira melhor de fazer isso? Mais elegância seria bom, e mais precisão seria melhor ainda.

Atualização

Tecnicamente eu tenho acesso a qualquer informação Javascript pode obter sobre a data. Eu tenho uma página na qual eu tenho colocado um campo oculto chamado "compensar". Eu tenho uma função JQuery que preenche o campo compensado com o DateTime (). GetTimezoneOffset (). Enquanto eu não vejo nada no objeto DateTime que vai ajudar, talvez isso vai abrir outros caminhos para idéias.

Foi útil?

Solução

Resposta curta:. Você não pode

O horário de verão tornam impossível. Por exemplo, não há nenhuma maneira de determinar, exclusivamente a partir de UTC offset, a diferença entre o Arizona e Califórnia no verão, ou Arizona e Novo México no inverno (desde Arizona não observa DST).

Há também a questão do que de tempo diferentes países observam DST. Por exemplo, na DST US começa mais cedo e termina mais tarde do que na Europa.

A suposição perto é possível (ou seja +/- uma hora), mas se você estiver usando-o para exibir tempo para os usuários você vai inevitavelmente exibir a hora errada para alguns deles.


Atualizar : A partir dos comentários, parece que o seu principal objetivo é exibir um timestamp no fuso horário local do usuário. Se é isso que você quer fazer, você deve enviar o tempo como um timestamp UTC, e em seguida, basta reescrevê-lo no navegador do usuário com Javascript. No caso em que eles não têm Javascript habilitado, eles ainda iria ver um UTC timestamp utilizável. Aqui é uma função que eu vim com a esta pergunta , que eu usei no este script Greasemonkey . Você pode querer ajustá-lo para atender às suas necessidades.

//@param timestamp An ISO-8601 timestamp in the form YYYY-MM-DDTHH:MM:SS±HH:MM
//Note: Some other valid ISO-8601 timestamps are not accepted by this function
function parseISO8601(timestamp)
{
  var regex = new RegExp("^([\\d]{4})-([\\d]{2})-([\\d]{2})T([\\d]{2}):([\\d]{2}):([\\d]{2})([\\+\\-])([\\d]{2}):([\\d]{2})$");
  var matches = regex.exec(timestamp);
  if(matches != null)
  {
    var offset = parseInt(matches[8], 10) * 60 + parseInt(matches[9], 10);
    if(matches[7] == "-")
      offset = -offset;

    return new Date(
      Date.UTC(
        parseInt(matches[1], 10),
        parseInt(matches[2], 10) - 1,
        parseInt(matches[3], 10),
        parseInt(matches[4], 10),
        parseInt(matches[5], 10),
        parseInt(matches[6], 10)
      ) - offset*60*1000
    );
  }
  return null;
}

Aqui está uma função que eu uso no meu blog para exibir um timestamp analisado no fuso horário local do usuário. Novamente, você pode ajustá-lo para o formato que você quiser.

var weekDays = new Array("Sunday", "Monday", "Tuesday", "Wednesday",
        "Thursday", "Friday", "Saturday");
var months = new Array("January", "February", "March", "April", "May", "June",
        "July", "August", "September", "October", "November", "December");

function toLocalTime(date)
{
  var hour = date.getHours();
  var ampm = (hour < 12 ? "am" : "pm");
  hour = (hour + 11)%12 + 1;

  var minutes = date.getMinutes();
  if(minutes < 10)
    minutes = "0" + minutes;

  return weekDays[date.getDay()] + ", "
       + months[date.getMonth()] + " "
       + date.getDate()          + ", "
       + date.getFullYear()      + " at "
       + hour                    + ":"
       + minutes                 + " "
       + ampm;
}

Outras dicas

Sabendo apenas o deslocamento do UTC, você não pode dizer o fuso horário em que está, por causa da DST. Você poderia considerar a olhar para a parte da hora do tempo para tentar adivinhar se DST estava em vigor, em seguida, ou não, mas considerações políticas que isso quase impossível, como diferentes jurisdições alterar a definição de DST.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top