Преобразование строк-строк с наносекундами

Я некоторое время боролся с этим кодом для Android-приложения, и я не могу его повесить. Я прочитал и пробовал все решения, которые я нашел в stackoverflow и других местах, но все равно не повезло.

То, что я хочу сделать, это иметь функцию для преобразования строки типа "17.08.2012 05:35:19:7600000" в дату UTC и функцию, которая принимает UTC date и преобразует ее в такую ​​строку.

String value = "17.08.2012 05:35:19:7600000";
DateFormat df = new SimpleDateFormat("dd.MM.yyyy HH:mm:ss:SSSSSSS");
try
{
  Date today = df.parse(value);
  System.out.println("Today = " + df.format(today) + " " + today.toGMTString());
} 
catch (ParseException e)
{
  e.printStackTrace();
}

В результате получается: Today = 17.08.2012 07:41:59:0000000 17 Aug 2012 04:41:59 GMT, которые являются неправильными.

Я попытался установить SDF timezone на UTC, не повезло.
Еще одна вещь, которую я заметил: если я делаю df.setLenient(false);
Это дает мне: java.text.ParseException: Unparseable date: "17.08.2012 05:35:19:7600000".

Если кто-нибудь может предоставить мне некоторые пояснения/образец кода, я был бы очень благодарен. Спасибо заранее

Ответ 1

Результат, который вы получаете, абсолютно прав.

Проанализируем это:

17.08.2012 05:35:19:7600000
  • 17: День месяца (17)
  • 08: Месяц года (август)
  • 2012: Год (2012)
  • 05: Час дня (5 утра)
  • 35: минута часа (: 35)
  • 19: Вторая минута (: 19)
  • 7600000: миллисекунды второго (7 600 000)

Теперь, как видит VM, вы заявляете время дня как 5:35:19, а затем добавляете к нему 7 600 000 миллисекунд. 7 600 000 миллисекунд = 7 600 секунд = 2 часа, 6 минут, 40 секунд. 5:35:19 am + 02:06:40 = 7:41:59 am (и 0 миллисекунд). Это результат, который вы получаете. (Также кажется, что вы не устанавливаете часовой пояс должным образом, поэтому строка GMT на 3 часа позади вашего результата.)

Если вы хотите сохранить :7600000, насколько мне известно, это невозможно. Так как это можно упростить в секундах, виртуальная машина автоматически уменьшит ее до другого времени. Миллисекунды (SSSS) должны быть для хранения значений < 1000.

Я предлагаю вам создать новый SimpleDateFormat для вашего вывода; но помните, что миллисекунды будут поглощены в другие времена (поскольку все они хранятся как один long в объекте Date).

Ответ 2

    private String convertDate(String cdate)
{
    SimpleDateFormat dateFormat = new SimpleDateFormat("dd.MM.yyyy HH:mm:ss:SSSSSSS");
    SimpleDateFormat postFormater = new SimpleDateFormat("yyyy-MM-dd");
    Date convertedDate;
    try
    {
        convertedDate = dateFormat.parse(cdate);
        cdate = postFormater.format(convertedDate);
    }
    catch (ParseException e)
    {
        Toast.makeText(getApplicationContext(),e.toString(),Toast.LENGTH_SHORT).show();
    }
    return cdate;
}

Попробуйте это.

Ответ 3

Это то, что вам нужно (но оно потеряет миллисекунду информации):

"dd.MM.yyyy HH:mm:ss.'000000'"

Если вы использовали "dd.MM.yyyy HH:mm:ss.SSSSSS", тогда получите три ведущих нуля за миллисекунды.

Если вы использовали "dd.MM.yyyy HH:mm:ss.SSS'000'", вы могли форматировать дату, но не анализировать дату.

Попробуйте:

public static void main(String[] args) throws ParseException {
    printDate("dd.MM.yyyy HH:mm:ss.SSS");//02.05.2010 21:45:58.073
    printDate("dd.MM.yyyy HH:mm:ss.SSSSSS");//02.05.2010 21:45:58.000073
    printDate("dd.MM.yyyy HH:mm:ss.SSS'000'");//02.05.2010 21:45:58.073000
    printDate("dd.MM.yyyy HH:mm:ss.'000000'");//02.05.2010 21:45:58.000000

    tryToParseDate("dd.MM.yyyy HH:mm:ss.SSS");//good
    tryToParseDate("dd.MM.yyyy HH:mm:ss.SSSSSS");//good
    tryToParseDate("dd.MM.yyyy HH:mm:ss.SSS'000'");//bad
    tryToParseDate("dd.MM.yyyy HH:mm:ss.'000000'");//good
}

private static void printDate(String formatString) {
    Date now = new Date();
    SimpleDateFormat format = new SimpleDateFormat(formatString);
    String formattedDate = format.format(now);

    // print that date
    System.out.println(formattedDate);
}

private static void tryToParseDate(String formatString) {
    Date now = new Date();
    SimpleDateFormat format = new SimpleDateFormat(formatString);
    String formattedDate = format.format(now);

    // try to parse it again
    try {
        format.parse(formattedDate);
        System.out.println("good");
    } catch (ParseException e) {
        System.out.println("bad");
    }
}