Javascript DateFormat для разных часовых поясов

Я разработчик Java, и я привык к классу SimpleDateFormat, который позволяет мне форматировать любую дату в любом формате с помощью настроек часового пояса.

Date date = new Date();

SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy hh:mm:ss");

sdf.setTimeZone(TimeZone.getTimeZone("America/Los_Angeles"));
System.out.println(sdf.format(date)); // Prints date in Los Angeles

sdf.setTimeZone(TimeZone.getTimeZone("America/Chicago"));
System.out.println(sdf.format(date)); // Prints same date in Chicago

SimpleDateFormat - довольно опрятное решение в Java, но, к сожалению, я не могу найти подобную альтернативу в Javascript.

Я продлеваю прототип Date в Javascript, чтобы сделать то же самое. У меня есть даты в формате Unix, но я хочу отформатировать их в разных часовых поясах.

Date.prototype.format = function(format, timezone) {
    // Now what?
    return formattedDate;
}

Я ищу аккуратный способ сделать это, а не взломать.

Спасибо

Ответ 1

У JavaScript нет встроенной поддержки для другого часового пояса, кроме локального. Вы можете указывать дату только по местному времени или по времени UTC. Невозможно изменить смещение часового пояса объекта Date.

Таким образом, нет "аккуратного" способа решения вашей проблемы.

Ответ 2

Формат ISO Extended для общей даты - YYYY-MM-DD, а для времени - hh: mm: ss. Любой формат можно понять, недвусмысленно, во всем мире.

См. также: http://jibbering.com/faq/#dates

Ответ 3

Не пишите свои собственные вещи; просто введите datejs: http://www.datejs.com/

Вы можете выяснить, какое смещение временной зоны установлено в среде выполнения следующим образом:

var local = new Date();
var utc = Date.UTC(local.getFullYear(), local.getMonth(), local.getDate(), local.getHours(), local.getMinutes(), local.getSeconds(), local.getMilliseconds());
var tz = (utc - local.getTime()) / (60 * 60 * 1000);

Ответ 4

Если вы просто передаете сырую TZ, ничего сложного в настройке часов нет. Мой пример ниже, конечно, сокращен. В зависимости от того, сколько шаблонов вы будете обрабатывать, может возникнуть довольно долго.

Date.prototype.format = function(format, tzAdjust) {
    // adjust timezone
    this.setHours(this.getHours()+tzAdjust)
    // pad zero helper - return "09" or "12"
    var two = function(s){ return s+"".length==1 ? "0"+s : s+""; }
    // replace patterns with date numbers
    return format.replace(/dd|MM|yyyy|hh|mm|ss/g, function(pattern){
        switch(pattern){
            case "d" : return this.getDate();
            case "dd" : return two(this.getDate());
        }
    });
}

Ответ 5

Попытка (настолько немного) улучшить предложение mwilcox:

Date.prototype.format = function(format, tzAdjust) {

    // get/setup a per-date-instance tzDate object store
    var tzCache = this.__tzCache = this.__tzCache || (this.__tzCache = {});

    // fetch pre-defined date from cache 
    var tzDate = tzCache[tzAdjust];
    if ( !tzDate )
    {
      // on miss - then create a new tzDate and cache it
      tzDate = tzCache[tzAdjust] = new Date( this );
      // adjust by tzAdjust (assuming it in minutes 
      // to handle those weird half-hour TZs :) 
      tzDate.setUTCMinutes( tzDate.getUTCMinutes()+tzAdjust );
    }

    return format.replace(/dd|MM|yyyy|hh|mm|ss/g, function(pattern){
               // replace each format tokens with a value 
               // based on tzDate corresponding UTC property
             });
}

Ответ 6

Вы четко задаете два вопроса в одном, форматировании и часовом поясе. Их нужно рассматривать отдельно. Форматирование довольно тривиально, если ни один из других ответов не сделает этого, вам придется быть более конкретным.

Что касается временного и часового поясов, если у вас есть сервер, который вводит время UTC, желательно как время UNIX в миллисекундах, в JavaScript, вы можете сравнить это с временем на клиентской машине и, таким образом, определить, насколько далеко от UTC клиент. Затем вы можете рассчитать время любого требуемого часового пояса.

Изменить: я на самом деле не знал, что JavaScript также был встроен в UTC, пока я не проверил в Интернете, аккуратно.

В любом случае, я предполагаю, что это хотите, вы хотите:

Date.prototype.format=function(format,timezone){
    var obj=new Date(this.getTime()+this.getTimezoneOffset()*60000+timezone*3600000);
    var two=function(s){
        return s<10?"0"+s:s+"";
    }
    return format.replace(/dd|MM|yyyy|hh|mm|ss/g, function(pattern){
        switch(pattern){
            case "dd" : return two(obj.getDate());
            case "MM" : return two(obj.getMonth()+1);
            case "yyyy" : return obj.getFullYear();
            case "hh" : return two(obj.getHours());
            case "mm" : return two(obj.getMinutes());
            case "ss" : return two(obj.getSeconds());
        }
    });
}

Если вам нужно, вы можете добавить больше шаблонов.

Ответ 7

Это старый вопрос, но так как я нашел его:

Как уже упоминалось, нет ничего разумного встроенного.

Что касается libs, то Moment Timezone для Moment.js.

Вот пример JSfiddle с примером: http://jsfiddle.net/kunycrkb/

Тот же самый код:

var m = moment("2014-06-01T13:05:00Z");
var f = "HH:mm z";

$("#results").text(m.tz("UTC").format(f) + " is " + m.tz("EST").format(f) +  "!");