Перетворити дату / час для заданого часового поясу - Java


80

Я хочу перетворити цю позначку часу GMT у GMT + 13:

2011-10-06 03:35:05

Я спробував близько 100 різних комбінацій DateFormat, TimeZone, Date, GregorianCalendar тощо, щоб спробувати виконати це ДУЖЕ базове завдання.

Цей код робить те, що я хочу НА ПОТОЧНИЙ ЧАС:

Calendar calendar = new GregorianCalendar(TimeZone.getTimeZone("GMT"));

DateFormat formatter = new SimpleDateFormat("dd MMM yyyy HH:mm:ss z");    
formatter.setTimeZone(TimeZone.getTimeZone("GMT+13"));  

String newZealandTime = formatter.format(calendar.getTime());

Але я хочу встановити час, а не використовувати поточний час.

Я виявив, що будь-коли намагаюся встановити час так:

calendar.setTime(new Date(1317816735000L));

використовується часовий пояс місцевої машини. Чому так? Я знаю, що коли "new Date ()" повертає час UTC + 0, то чому при встановленні часу в мілісекундах він більше не припускає, що час у UTC?

Чи можна:

  1. Встановіть час на об'єкті (Календар / Дата / Мітка часу)
  2. (Можливо) Встановіть часовий пояс початкової позначки часу (calendar.setTimeZone (...))
  3. Відформатуйте позначку часу за допомогою нового часового поясу (formatter.setTimeZone (...)))
  4. Повернути рядок з новим часом часового поясу. (formatter.format (calendar.getTime ()))

Заздалегідь дякую за будь-яку допомогу: D


Забагато запитань в одному дописі ...
Barmaley

Ті самі 2 запитання, задані лише другому, задаються вдруге з алгоритмом сценарію для ясності. Дякуємо за вхід tho:?
travega

Здається, єдина проблема полягає в тому 1317816735000L, що неправильна позначка часу для 2011-10-06 03:35:05 GMT. Інакше ваш підхід правильний.
серпень

1
FYI, клопітні старі класи часу та часу, такі як java.util.Date, java.util.Calendarі java.text.SimpleDateFormatтепер є застарілими , витіснені класами java.time, вбудованими в Java 8 та пізніші версії. Див. Підручник Oracle .
Василь Бурк

Відповіді:


62

Для мене найпростіший спосіб зробити це:

Calendar calendar = Calendar.getInstance();
calendar.setTime(new Date());
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");

//Here you say to java the initial timezone. This is the secret
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
//Will print in UTC
System.out.println(sdf.format(calendar.getTime()));    

//Here you set to your timezone
sdf.setTimeZone(TimeZone.getDefault());
//Will print on your default Timezone
System.out.println(sdf.format(calendar.getTime()));

1
@Charleston Що reviewв черзіdate = sdf.parse(review);
09Q71AO534

1
@Charleston Але в SDF немає такого типу методу, sdf.parse(DateObject)він не визначений у Java, який я використовую JDK.1.7.
09Q71AO534

Мені так шкода моєї другої відповіді. Я навіть не тестував! Але зараз Його перевірено та працює!
Чарльстон,

1
Як отримати фактичну дату замість рядка?
Tulains Córdova

1
Може бути, це має бути: SimpleDateFormat ("рррр-ММ-дд год: мм: сс")
Маркос

31

Розуміння того, як працює комп’ютерний час, є дуже важливим. З цим я погоджуюсь, що якщо API створений, щоб допомогти вам обробляти комп’ютерний час як реальний час, він повинен працювати таким чином, що дозволяє обробляти його як реальний час. Здебільшого це так, але є деякі основні недогляди, які потребують уваги.

У будь-якому разі я відступаюсь !! Якщо у вас є зміщення UTC (краще працювати в UTC, ніж зміщення GMT), ви можете обчислити час в мілісекундах і додати його до своєї позначки часу. Зауважте, що мітка часу SQL може відрізнятися від мітки часу Java, оскільки спосіб обчислення епохи не завжди однаковий - залежить від технологій баз даних, а також операційних систем.

Я б порадив вам використовувати System.currentTimeMillis () як ваші часові мітки, оскільки їх можна більш послідовно обробляти в Java, не турбуючись про перетворення SQL Timestamps у об'єкти Java-дати тощо.

Для обчислення компенсації ви можете спробувати щось подібне:

Long gmtTime =1317951113613L; // 2.32pm NZDT
Long timezoneAlteredTime = 0L;

if (offset != 0L) {
    int multiplier = (offset*60)*(60*1000);
    timezoneAlteredTime = gmtTime + multiplier;
} else {
    timezoneAlteredTime = gmtTime;
}

Calendar calendar = new GregorianCalendar();
calendar.setTimeInMillis(timezoneAlteredTime);

DateFormat formatter = new SimpleDateFormat("dd MMM yyyy HH:mm:ss z");

formatter.setCalendar(calendar);
formatter.setTimeZone(TimeZone.getTimeZone(timeZone));

String newZealandTime = formatter.format(calendar.getTime());

Сподіваюся, це корисно!


@ user726478 Чи правильно це, коли ми знаємо рядок часового поясу? long timezoneAlteredTime = gmtTime + TimeZone.getTimeZone ("Азія / Калькутта"). getRawOffset (); "
Канагавелу Сугумар

4
Не добре. Зміщення часового поясу не є постійним. Це залежить від фактичної дати.
Дмитро Трифонов

1
Як отримати фактичну дату замість рядка?
Тулен Кордова

@KanagaveluSugumar тут компенсується годинами
МОЄ

25

Як завжди, я рекомендую прочитати цю статтю про дату та час на Java, щоб ви це зрозуміли.

Основна ідея полягає в тому, що `` під капотом '' все робиться в мілісекундах UTC з часу. Це означає, що найпростіше, якщо ви працюєте взагалі без часових поясів, за винятком форматування рядка для користувача.

Тому я пропустив би більшість із запропонованих вами кроків.

  1. Встановіть час на об'єкті (Дата, Календар тощо).
  2. Встановіть часовий пояс на об'єкті форматування.
  3. Повернення рядка з форматування.

Крім того, ви можете використовувати Joda time . Я чув, що це набагато інтуїтивніший API дати та часу.


Привіт, Bringer128, дякую за вашу відповідь, мені просто здається смішним, що немає прямого способу налаштування часової позначки для даного часового поясу. Навіщо включати функціонал, якщо все, що він робить, змінює тег часового поясу у відформатованому рядку ... Я спробую Joda time. Дякую
travega

@travega Існує простий спосіб, якщо ви представляєте свій час як UTC і форматуєте його за допомогою SimpleDateFormat. Змінюється не лише частина „Z” (тег часового поясу), але і ціла дата. Перевірте результати встановлення двох різних об’єктів SimpleDateFormat із різними часовими поясами, коли вони форматують одну і ту ж дату.
Bringer128,

Як отримати фактичну дату замість рядка?
Tulains Córdova

@ TulainsCórdova Я думаю, вам потрібно буде пояснити більш докладно. Чи можете ви створити запитання або здійснити пошук відповідного питання, яке може вирішити ваше конкретне питання?
Bringer128

19

tl; д-р

Instant.ofEpochMilli( 1_317_816_735_000L )
    .atZone( ZoneId.of( "Pacific/Auckland" ) )
    .format( DateTimeFormatter.ofLocalizedDateTime( FormatStyle.MEDIUM ).withLocale( new Locale( "en" , "NZ" ) ) )

... також ...

LocalDateTime.parse( "2011-10-06 03:35:05".replace( " " , "T" ) )
    .atZone( ZoneId.of( "Pacific/Auckland" ) )

java.time

Питання та більшість відповідей використовують застарілі застарілі класи дати та часу з найперших версій Java. Ці старі класи виявилися складними та заплутаними. Уникайте їх. Натомість використовуйте класи java.time.

ISO 8601

Ваш вхідний рядок майже у стандартному форматі ISO 8601. Просто замініть ПРОСТІР посередині на T.

String input = "2011-10-06 03:35:05".replace( " " , "T" );

LocalDateTime

Тепер проаналізуйте як a, LocalDateTimeоскільки на вході відсутня будь-яка інформація про зсув від UTC або часовий пояс. A LocalDateTimeне має поняття зсуву та часового поясу, тому не відображає фактичний момент на часовій шкалі.

LocalDateTime ldt = LocalDateTime.parse( input );

ZoneOffset

Ви, схоже, хочете сказати, що з ділового контексту ви знаєте, що намір цього рядка - представити момент, який випереджає UTC на 13 годин. Отже, ми створюємо екземпляр a ZoneOffset.

ZoneOffset offset = ZoneOffset.ofHours( 13 ); // 13 hours ahead of UTC, in the far east of the globe.

OffsetDateTime

Застосуйте його, щоб отримати OffsetDateTimeоб’єкт. Це стає актуальним моментом на часовій шкалі.

OffsetDateTime odt = ldt.atOffset( offset);

ZoneId

Але тоді ви згадуєте Нову Зеландію. Отже, ви мали на увазі конкретний часовий пояс. Часовий пояс - це зсув від UTC плюс набір правил для обробки аномалій, таких як літній час. Таким чином, ми можемо вказати ZoneIda, ZonedDateTimeа не просто зміщення.

Вкажіть правильну назву часового поясу . Ніколи не використовуйте абревіатури з 3-4 букв, такі як ESTабо, ISTоскільки вони не є справжніми часовими поясами, не стандартизовані і навіть не унікальні (!). Наприклад, Pacific/Auckland.

ZoneId z = ZoneId.of( "Pacific/Auckland" );

ZonedDateTime

Застосувати ZoneId.

ZonedDateTime zdt = ldt.atZone( z );

Ви можете легко перейти в іншу зону на той самий момент на часовій шкалі.

ZoneId zParis = ZoneId.of( "Europe/Paris" );
ZonedDateTime zdtParis = zdt.withZoneSameInstant( zParis );  // Same moment in time, but seen through lens of Paris wall-clock time.

Відлік від епохи

Я настійно рекомендую не обробляти значення дати та часу як відлік від епохи, наприклад, мілісекунди від початку 1970 UTC. Але якщо потрібно, створіть Instantіз такого числа.

Instant instant = Instant.ofEpochMilli( 1_317_816_735_000L );

Потім, за бажанням, призначте часовий пояс, як показано вище, щоб відійти від UTC.

ZoneId z = ZoneId.of( "Pacific/Auckland" );
ZonedDateTime zdt = instant.atZone( z );

Ваше значення 1_317_816_735_000L:

  • 2011-10-05T12:12:15Z (Середа, 05 жовтня 2011, 12:12:15 GMT)
  • 2011-10-06T01:12:15+13:00[Pacific/Auckland] (Четвер, 6 жовтня 2011, 01:12:15 в Окленді, Нова Зеландія).

Створення рядків

Щоб згенерувати рядок у стандартному форматі ISO 8601 , просто зателефонуйте toString. Зверніть увагу, що ZonedDateTimeрозумно розширює стандартний формат, додаючи назву часового поясу у квадратні дужки.

String output = zdt.toString();

Для інших форматів шукайте DateTimeFormatterклас переповнення стека . Вже охоплювали багато разів.

Вкажіть a FormatStyleта a Locale.

Locale l = new Locale( "en" , "NZ" );
DateTimeFormatter f = DateTimeFormatter.ofLocalizedDateTime( FormatStyle.MEDIUM ).withLocale( l );
String output = zdt.format( f );

Зверніть увагу, що часовий пояс не має нічого спільного з мовою. Ви можете вказати Europe/Parisдату-час японською мовою та культурними нормами, або aAsia/Kolkata дату-час, відображену португальською мовою та культурними нормами Бразилії.

Про java.time

Java.time каркас вбудований в Java 8 і пізніших версій. Ці класи витісняти неприємні старі класи дати і часу , такі як java.util.Date, .Calendar, і java.text.SimpleDateFormat.

Проект Joda-Time , який зараз знаходиться в режимі технічного обслуговування , радить перейти на java.time.

Щоб дізнатись більше, див. Підручник Oracle . І шукайте в Stack Overflow багато прикладів та пояснень.

Значна частина функцій java.time переноситься назад на Java 6 і 7 у ThreeTen-Backport і додатково адаптується до Android у ThreeTenABP (див. Як користуватися… ).

Проект ThreeTen-Extra розширює java.time додатковими класами. Цей проект є полігоном для можливих майбутніх доповнень до java.time. Ви можете знайти деякі корисні класи тут , такі як Interval, YearWeek, YearQuarterі багато інших.


10

Рішення насправді досить просте (чиста, проста Java):

System.out.println(" NZ Local Time: 2011-10-06 03:35:05");
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
LocalDateTime localNZ = LocalDateTime.parse("2011-10-06 03:35:05",formatter);
ZonedDateTime zonedNZ = ZonedDateTime.of(localNZ,ZoneId.of("+13:00"));
LocalDateTime localUTC = zonedNZ.withZoneSameInstant(ZoneId.of("UTC")).toLocalDateTime();
System.out.println("UTC Local Time: "+localUTC.format(formatter));

ВИХІД Є:

 NZ Local Time: 2011-10-06 03:35:05
UTC Local Time: 2011-10-05 14:35:05

1
Це було вирішено 4 роки тому, і ваше рішення не додає нічого нового.
travega

1
Я думаю, що це новий підхід із використанням Java 8, але якість відповіді низька.
Перемек

6

Подивився, і я не думаю, що на Java існує часовий пояс GMT + 13. Тому я думаю, вам доведеться використовувати:

Calendar calendar = Calendar.getInstance();
//OR Calendar.getInstance(TimeZone.getTimeZone("GMT"));

calendar.set(Calendar.HOUR_OF_DAY, calendar.get(Calendar.HOUR_OF_DAY)+13);

Date d = calendar.getTime();

(Якщо є тоді, змініть "GMT" на цей часовий пояс і видаліть 2-й рядок коду)

АБО

SimpleDateFormat df = new SimpleDateFormat();
df.setTimeZone(TimeZone.getTimeZone("GMT+13"));
System.out.println(df.format(c.getTime()));

Якщо ви хочете встановити конкретний час / дату, ви також можете використовувати:

    calendar.set(Calendar.DATE, 15);
calendar.set(Calendar.MONTH, 3);
calendar.set(Calendar.YEAR, 2011);
calendar.set(Calendar.HOUR_OF_DAY, 13); 
calendar.set(Calendar.MINUTE, 45);
calendar.set(Calendar.SECOND, 00);

1
Гей, Крейг, дякую за вашу відповідь. Java не підтримує / не підтримує стандарти часу ISO GMT - це глобальний стандарт часу, який модерується незалежно від Java. Час / календар Apis дотримуються стандарту, а GMT + 13 стосується NZDT або переходу на літній час у будь-якій зоні GMT + 12. Що стосується вашого зразка коду, у мене ваш сценарій працює без будь-яких проблем, як зазначено в моєму IP. Проблема, з якою я стикаюся, полягає у визначенні часової позначки та виведенні точних варіантів оригінальної позначки часового поясу, а НЕ виведення поточного часу, що і робить ваш код. Дякую T
travega

3

Ми можемо впоратися з цим, використовуючи значення зміщення

 public static long convertDateTimeZone(long lngDate, String fromTimeZone,
        String toTimeZone){
    TimeZone toTZ = TimeZone.getTimeZone(toTimeZone);
    Calendar toCal = Calendar.getInstance(toTZ);        

    TimeZone fromTZ = TimeZone.getTimeZone(fromTimeZone);
    Calendar fromCal = Calendar.getInstance(fromTZ);
    fromCal.setTimeInMillis(lngDate);
    toCal.setTimeInMillis(fromCal.getTimeInMillis()
            + toTZ.getOffset(fromCal.getTimeInMillis())
            - TimeZone.getDefault().getOffset(fromCal.getTimeInMillis()));      
    return toCal.getTimeInMillis();
}

Фрагмент тестового коду:

 System.out.println(new Date().getTime())
 System.out.println(convertDateTimeZone(new Date().getTime(), TimeZone
                .getDefault().getID(), "EST"));

Вихід: 1387353270742 1387335270742


2

Я спробував цей код

try{
            SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy hh:mm:ss Z");
            Date datetime = new Date();

            System.out.println("date "+sdf.format(datetime));

            sdf.setTimeZone(TimeZone.getTimeZone("GMT"));

            System.out.println("GMT "+ sdf.format(datetime));

            sdf.setTimeZone(TimeZone.getTimeZone("GMT+13"));

            System.out.println("GMT+13 "+ sdf.format(datetime));

            sdf.setTimeZone(TimeZone.getTimeZone("UTC"));

            System.out.println("utc "+sdf.format(datetime));

            Calendar calendar = new GregorianCalendar(TimeZone.getTimeZone("GMT"));

            DateFormat formatter = new SimpleDateFormat("dd MMM yyyy HH:mm:ss z");    
            formatter.setTimeZone(TimeZone.getTimeZone("GMT+13"));  

            String newZealandTime = formatter.format(calendar.getTime());

            System.out.println("using calendar "+newZealandTime);

        }catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

і отримати цей результат

date 06-10-2011 10:40:05 +0530
GMT 06-10-2011 05:10:05 +0000 // here getting 5:10:05
GMT+13 06-10-2011 06:10:05 +1300 // here getting 6:10:05
utc 06-10-2011 05:10:05 +0000
using calendar 06 Oct 2011 18:10:05 GMT+13:00

Привіт, Пратік, дякую за вступ, але ти пропустив суть. Як вже згадувалося в моєму ІР, я працюю на поточний час. Проблема полягає у встановленні позначки часу, а потім у формуванні точного виходу для конкретного часового поясу.
travega

так, це також спрацює, якщо змінити час. Часовий пояс був встановлений в об'єкті форматування, тому будь-який час, який ви пройшли, буде базуватися на часовому поясі, який був вказаний у об'єкті форматування
Пратік

Хм-м-м-м ... я спробував додати: datetime.setTime (Timestamp.valueOf ("06.10.2011 03:35:05"). GetTime ()); І все одно це не працює. Як ви вважаєте, що це працює, коли ви встановлюєте час?
travega

@Pratik: Як я можу отримати часовий пояс AST.
Вед Пракаш

2

Joda-Time

Класи java.util.Date/Calendar в хаосі і їх слід уникати.

Оновлення: Проект Joda-Time перебуває в режимі обслуговування. Команда радить перейти на заняття java.time.

Ось ваша відповідь за допомогою бібліотеки Joda-Time 2.3. Дуже легко.

Як зазначено у прикладі коду, я пропоную вам використовувати іменовані часові пояси, де це можливо, щоб ваше програмування могло обробляти літній час (DST) та інші аномалії.

Якщо ви розмістили a Tв середині рядка, а не пробіл, ви можете пропустити перші два рядки коду, маючи справу з форматором для синтаксичного аналізу рядка. Конструктор DateTime може приймати рядок у форматі ISO 8601 .

// © 2013 Basil Bourque. This source code may be used freely forever by anyone taking full responsibility for doing so.
// import org.joda.time.*;
// import org.joda.time.format.*;

// Parse string as a date-time in UTC (no time zone offset).
DateTimeFormatter formatter = org.joda.time.format.DateTimeFormat.forPattern( "yyyy-MM-dd' 'HH:mm:ss" );
DateTime dateTimeInUTC = formatter.withZoneUTC().parseDateTime( "2011-10-06 03:35:05" );

// Adjust for 13 hour offset from UTC/GMT.
DateTimeZone offsetThirteen = DateTimeZone.forOffsetHours( 13 );
DateTime thirteenDateTime = dateTimeInUTC.toDateTime( offsetThirteen );

// Hard-coded offsets should be avoided. Better to use a desired time zone for handling Daylight Saving Time (DST) and other anomalies.
// Time Zone list… http://joda-time.sourceforge.net/timezones.html
DateTimeZone timeZoneTongatapu = DateTimeZone.forID( "Pacific/Tongatapu" );
DateTime tongatapuDateTime = dateTimeInUTC.toDateTime( timeZoneTongatapu );

Скинути ці значення ...

System.out.println( "dateTimeInUTC: " + dateTimeInUTC );
System.out.println( "thirteenDateTime: " + thirteenDateTime );
System.out.println( "tongatapuDateTime: " + tongatapuDateTime );

При запуску ...

dateTimeInUTC: 2011-10-06T03:35:05.000Z
thirteenDateTime: 2011-10-06T16:35:05.000+13:00
tongatapuDateTime: 2011-10-06T16:35:05.000+13:00

2

відображати дату та час для всіх часових поясів

import java.util.Calendar;
import java.util.TimeZone;
import java.text.DateFormat;
import java.text.SimpleDateFormat;



static final String ISO8601 = "yyyy-MM-dd'T'HH:mm:ssZ";
DateFormat dateFormat = new SimpleDateFormat(ISO8601);
Calendar c = Calendar.getInstance();
String formattedTime;
for (String availableID : TimeZone.getAvailableIDs()) {
    dateFormat.setTimeZone(TimeZone.getTimeZone(availableID));
    formattedTime = dateFormat.format(c.getTime());
    System.out.println(formattedTime + " " + availableID);
}

1

Ми можемо отримати позначку часу UTC / GMT з даної дати.

/**
 * Get the time stamp in GMT/UTC by passing the valid time (dd-MM-yyyy HH:mm:ss)
 */
public static long getGMTTimeStampFromDate(String datetime) {
    long timeStamp = 0;
    Date localTime = new Date();

    String format = "dd-MM-yyyy HH:mm:ss";
    SimpleDateFormat sdfLocalFormat = new SimpleDateFormat(format);
    sdfLocalFormat.setTimeZone(TimeZone.getDefault());

    try {

        localTime = (Date) sdfLocalFormat.parse(datetime); 

        Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC"),
                Locale.getDefault());
        TimeZone tz = cal.getTimeZone();

        cal.setTime(localTime);

        timeStamp = (localTime.getTime()/1000);
        Log.d("GMT TimeStamp: ", " Date TimegmtTime: " + datetime
                + ", GMT TimeStamp : " + localTime.getTime());

    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    return timeStamp;

}

Він поверне час UTC відповідно до минулої дати.

  • Ми можемо зробити зворотну позначку, як відмітку часу UTC, до поточної дати та часу (навпаки)

        public static String getLocalTimeFromGMT(long gmtTimeStamp) {
                 try{
                        Calendar calendar = Calendar.getInstance();
                        TimeZone tz = TimeZone.getDefault();
                        calendar.setTimeInMillis(gmtTimeStamp * 1000);
        //              calendar.add(Calendar.MILLISECOND, tz.getOffset(calendar.getTimeInMillis())); 
                        SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
                        Date currenTimeZone = (Date) calendar.getTime();
                        return sdf.format(currenTimeZone);
                    }catch (Exception e) {
                    }
                    return "";  
                }
    

Сподіваюсь, це допоможе іншим. Дякую!!


1

Швидкий спосіб:

String dateText ="Thu, 02 Jul 2015 21:51:46";
long hours = -5; // time difference between places

DateTimeFormatter formatter = DateTimeFormatter.ofPattern(E, dd MMM yyyy HH:mm:ss, Locale.ENGLISH);     
LocalDateTime date = LocalDateTime.parse(dateText, formatter);        
date = date.with(date.plusHours(hours));

System.out.println("NEW DATE: "+date);

Вихідні дані

НОВА ДАТА: 2015-07-02T16: 51: 46


1

Ваш підхід працює без будь-яких змін.

Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
// Timestamp for 2011-10-06 03:35:05 GMT
calendar.setTime(new Date(1317872105000L));

DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z"); 
formatter.setTimeZone(TimeZone.getTimeZone("GMT+13"));

// Prints 2011-10-06 16:35:05 GMT+13:00
System.out.println(formatter.format(calendar.getTime()));

1
public Timestamp convertLocalTimeToServerDatetime(String dt,String timezone){

    String clientDnT = dt ;// "2017-06-01 07:20:00";
    try{
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    Date date = sdf.parse(clientDnT);
    TimeZone tz = TimeZone.getTimeZone(timezone.trim()); // get time zone of user
    sdf.setTimeZone(tz);

    // Convert to servertime zone 
    SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    TimeZone tzInAmerica = TimeZone.getDefault();
    sdf1.setTimeZone(tzInAmerica);

    // assign date to date
    String serverDate = sdf1.format(date);

    // Convert to servertime zone to Timestamp
    Date date2 =  sdf.parse(serverDate);
    Timestamp tsm = new Timestamp(date2.getTime());
    return  tsm;
    }
    catch(Exception e){
        System.err.println(e);
    }

    return null;
}

будь ласка, передайте дату та часовий пояс клієнта , потім метод повертає позначку часу сервера .. для javascript var _timezone = Intl.DateTimeFormat().resolvedOptions().timeZone; та у java TimeZone tz = TimeZone.getDefault(); tz.getID()
Sourav Barman 02

1

Щоб знайти тривалість або інтервал часу з двома різними часовими поясами

import org.joda.time.{DateTime, Period, PeriodType}

val s1 = "2019-06-13T05:50:00-07:00"
val s2 = "2019-10-09T11:30:00+09:00"    

val period = new Period(DateTime.parse(s1), DateTime.parse(s2), PeriodType dayTime())

period.getDays
period.getMinutes
period.getHours

вихідний період = P117DT13H40M

days = 117
minutes = 40
hours = 13

1

Я хотів би надати сучасну відповідь.

Ви не повинні дуже бажати перетворювати дату та час із рядка з одним зміщенням GMT у рядок з іншим зміщенням GMT і з в іншому форматі. Швидше у вашій програмі зберігайте миттєвість (момент часу) як належний об’єкт дати та часу. Тільки тоді, коли вам потрібно надати рядок, відформатуйте об’єкт у потрібний рядок.

java.time

Розбір вводу

    DateTimeFormatter formatter = new DateTimeFormatterBuilder()
            .append(DateTimeFormatter.ISO_LOCAL_DATE)
            .appendLiteral(' ')
            .append(DateTimeFormatter.ISO_LOCAL_TIME)
            .toFormatter();

    String dateTimeString = "2011-10-06 03:35:05";
    Instant instant = LocalDateTime.parse(dateTimeString, formatter)
            .atOffset(ZoneOffset.UTC)
            .toInstant();

Для більшості цілей Instantце хороший вибір для зберігання моменту часу. Якщо вам потрібно було чітко вказати, що дата та час прийшли з GMT, використовуйте OffsetDateTimeзамість.

Перетворення, форматування та друк

    ZoneId desiredZone = ZoneId.of("Pacific/Auckland");
    Locale desiredeLocale = Locale.forLanguageTag("en-NZ");
    DateTimeFormatter desiredFormatter = DateTimeFormatter.ofPattern(
            "dd MMM uuuu HH:mm:ss OOOO", desiredeLocale);

    ZonedDateTime desiredDateTime = instant.atZone(desiredZone);
    String result = desiredDateTime.format(desiredFormatter);
    System.out.println(result);

Це надруковано:

06 жовтня 2011 16:35:05 GMT + 13: 00

Я вказав часовий пояс Тихий океан / Окленд, а не зсув, який ви згадали, +13: 00. Я зрозумів, що ти хотів новозеландський час, і Тихий океан / Окленд краще розповідає це читачеві. Часовий пояс також враховує літній час (літній час), тому вам не потрібно враховувати це у власному коді (для більшості цілей).

Оскільки Octмова англійською мовою, непогано надати програмувальнику явний регіон. GMTможе бути і локалізованим, але я думаю, що він просто друкується GMTу всіх мовах.

OOOOу рядку шаблону формату - це один із способів друку зміщення, що може бути кращою ідеєю, ніж друк абревіатури часового поясу, яку ви отримаєте, zоскільки абревіатури часових поясів часто неоднозначні. Якщо хочете NZDT(для літнього часу в Новій Зеландії), просто помістіть zтам.

Ваші запитання

Я відповім на ваші пронумеровані запитання стосовно сучасних класів у java.time.

Можна:

  1. Встановіть час на об'єкті

Ні, сучасні класи незмінні. Вам потрібно створити об’єкт, який має бажану дату та час з самого початку (це має ряд переваг, включаючи безпеку потоків).

  1. (Можливо) Встановіть часовий пояс початкової позначки часу

atZoneМетод , який я використовую в коді повертає ZonedDateTimeіз заданою тимчасової зоною. Інші класи часу та часу мають подібний метод, який іноді називають atZoneSameInstantіншими назвами.

  1. Відформатуйте позначку часу за допомогою нового часового поясу

Перетворення java.time на новий часовий пояс та форматування - це два окремі кроки, як показано.

  1. Повернути рядок з новим часом часового поясу.

Так, перетворити на бажаний часовий пояс, як показано, і відформатувати, як показано.

Я виявив, що будь-коли намагаюся встановити час так:

calendar.setTime(new Date(1317816735000L));

використовується часовий пояс місцевої машини. Чому так?

Це не так, як ти думаєш, що добре показує лише пару (багатьох) проблем дизайну зі старими класами.

  • A Dateне має часового поясу. Тільки коли ви надрукуєте його, його toStringметод захоплює ваш місцевий часовий пояс і використовує його для відтворення рядка. Це справедливо дляnew Date() . Така поведінка бентежила багатьох, багатьох програмістів за останні 25 років.
  • A Calender має часовий пояс. Це не змінюється, коли ти це робиш calendar.setTime(new Date(1317816735000L));.

Посилання

Підручник Oracle: Дата Час, що пояснює, як використовувати java.time.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.