Почему эпоха ColdFusion на один час отстает от эпохи javascript?

Я пишу приложение, где мне нужно получить время эпохи на стороне сервера, используя ColdFusion 8, работающую на Windows Server 2008 и на стороне клиента, используя javascript (тестирование в Google Chrome). Проблема в том, что время эпохи, созданное ColdFusion, на один час ниже, чем у javascript. Я проверил, что настройки даты и времени верны как на стороне клиента, так и на стороне сервера.

Вот как я устанавливаю временную метку с ColdFusion:

<cfset cfEpoch = DateDiff("s", "January 1 1970 00:00", DateConvert("Local2utc", now()))>

И вот как я устанавливаю его с помощью javascript:

var jsEpoch = Math.round(new Date().getTime()/1000.0);

Эпоха javascript соответствует той, что находится на этом сайте (http://www.epochconverter.com/), что имеет смысл, потому что они используют тот же метод, что и я с помощью. Эпоха ColdFusion отстает на один час. Здесь я попытался разобраться в этом:

<cfset localDate = now()>
<cfset utcDate = DateConvert("Local2utc", localDate)>
<cfset epoch = DateDiff("s", "January 1 1970 00:00", utcDate)>

<cfoutput>
    Local Date: #localDate# <br>
    UTC Date: #utcDate# <br>
    Epoch: #epoch#
</cfoutput>

Этот код выводит:

Local Date: {ts '2013-04-30 17:44:56'} 
UTC Date: {ts '2013-04-30 21:44:56'} 
Epoch: 1367354696

Так что я в недоумении. Правильно указаны значения даты и даты по локальной дате. Похоже, что единственное объяснение заключается в том, что функция DateDiff() работает некорректно, но я тестировал ее с другими датами, и, похоже, она работает нормально. Я полагаю, что могу просто добавить 3600 к значению эпохи, которое он генерирует, но я бы предпочел не делать этого, не зная, почему я получаю неправильное значение в первую очередь. Кто-нибудь видит, что мне здесь не хватает?

Ответ 1

Написав немного script, вы можете заметить что-то очень странное.

Это то, что он выводит для меня.

  • 1367360584 - Время в Javascript
  • 1367360594 - Эпоха секунд (преобразование эпохи в местное время)
  • 1367356994 - Epoch seconds (преобразование локального времени в UTC)

Таким образом, переход эпохи к местному времени происходит, но наоборот. Это также работает на CF8, поэтому, если вы конвертируете Epoch в местное время, похоже, что все правильно.

Попробуйте.

<script>
var jsEpoch = Math.round(new Date().getTime()/1000.0);
document.write(jsEpoch + ' - Javascript time <br>');
</script>


<cfset TheDate = now()>
<cfoutput>
#DateDiff("s",DateConvert("utc2Local", "January 1 1970 00:00"), TheDate)# - Epoch seconds (convert Epoch to local time)<br>
#DateDiff("s", "January 1 1970 00:00", DateConvert("Local2utc", TheDate))# - Epoch seconds (convert local time to UTC)
</cfoutput>

Ответ 2

ColdFusion 8 довольно старый, поэтому вы должны проверить свою версию JVM. Возможно, вы используете устаревшую версию, которая не учитывает новые правила DST. См. этот форум Adobe для более:

"Правила экономии дневного света США изменились с тех пор, как эта версия ColdFusion, и это подчеркивает JRE, где выпущено. Тебе нужно обновите JRE по крайней мере до 1,6.12, чтобы получить новые правила".

Забастовкa >

ОБНОВЛЕНО:

После дальнейшего тестирования JVM не является проблемой. Я получаю те же результаты, что и выше, на CF9, и мы уже прошли временные рамки, когда старые правила и новые правила возвращают разные результаты.

Однако, вот несколько способов получить правильный результат (спасибо Gavin):

function getEpoch(date localDate=now()){
    return dateDiff('s', dateConvert('utc2Local', createDateTime(1970, 1, 1, 0, 0, 0)), localDate);
}

Или вы можете получить доступ к базовому методу Java (оберните результат в int(), чтобы удалить десятичную):

int(createObject('java', 'java.lang.System').currentTimeMillis()/1000);

Ответ 3

Это адский час. Время Unix должно быть в секундах от 1970 в UTC. Но они, как Coldfusion и railo делают это, вам нужно добавить секунды с сервера, а не utc. Преобразуйте 1970 в "localServer time", затем добавьте секунды, затем конвертируйте обратно в UTC. Кажется, что при конвертации в UTC он просто сдвигает час и не применяет правила UTC DST. Это верно:

UTC из UNIX:

CreateODBCDateTime(DateConvert("local2Utc", DateAdd("s", #UNIXTIME#, DateConvert("utc2Local", "January 1 1970 00:00"))) )

UNIX FROM no local local:

DateDiff("s",DateConvert("utc2Local", "January 1 1970 00:00"), dateAdd('h',-timezone_hours_local_to_server, #LOCALTIME#))