C言語の asctime 関数がフォーマットする日時文字列を Java でパースする

## 概要
- C言語の asctime 関数がフォーマットする日時文字列を Java でパースする
- java.time.format.DateTimeFormatter クラスを使用する

## asctime 関数とは

asctime 関数は、時刻情報を人が読みやすい形式の日時文字列に変換する関数。

[asctime\(\) — 時間から文字ストリングへの変換](https://www.ibm.com/support/knowledgecenter/ja/ssw_ibm_i_73/rtref/asctime.htm)

> asctime() 関数は 24 時間クロック形式を使用します。曜日は、Sun、Mon、Tue、Wed、Thu、Fri、および Sat に省略されます。月は、Jan、Feb、Mar、Apr、May、Jun、Jul、Aug、Sep、Oct、Nov、および Dec に省略されます。すべてのフィールドには固定幅があります。一桁しかない日付は、ゼロまたはブランク・スペースが その前に置かれます。改行文字 (\n) および NULL 文字 (\0) がストリングの最後の位置を占めます。

asctime 関数は以下のようなアルゴリズムで文字列をフォーマットしている。

[asctime](https://pubs.opengroup.org/onlinepubs/007908799/xsh/asctime.html)

> The asctime() function converts the broken-down time in the structure pointed to by timeptr into a string in the form:
> 
> Sun Sep 16 01:03:52 1973\n\0
> 
> using the equivalent of the following algorithm:

```c
char *asctime(const struct tm *timeptr)
{
    static char wday_name[7][3] = {
        "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
    };
    static char mon_name[12][3] = {
        "Jan", "Feb", "Mar", "Apr", "May", "Jun",
        "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
    };
    static char result[26];

    sprintf(result, "%.3s %.3s%3d %.2d:%.2d:%.2d %d\n",
        wday_name[timeptr->tm_wday],
        mon_name[timeptr->tm_mon],
        timeptr->tm_mday, timeptr->tm_hour,
        timeptr->tm_min, timeptr->tm_sec,
        1900 + timeptr->tm_year);
    return result;
}
```

## C言語による asctime 関数を使用して日時文字列を出力するサンプルコード

ソースコード。

```c
#include <time.h>
#include <stdio.h>

int main(void) {

  time_t my_time;
  struct tm *my_local_time;
  char *str;

  /* 現在時刻(1970年1月1日00:00:00から数えた秒数)を取得 */
  time(&my_time);

  /* ローカル日時に変換 */
  my_local_time = localtime(&my_time);

  /* 人が読める形式の日時文字列に変換 */
  str = asctime(my_local_time);

  printf("%s", str);
}
```

ソースコードをコンパイル。

```
$ gcc mytime.c 
```

実行結果。

```
$ ./a.out 
Sun Dec  1 15:27:08 2019
```

## Java による asctime 関数フォーマット日時文字列をパースするサンプルコード

ソースコード。

```java
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAccessor;
import java.util.Date;
import java.util.Locale;

public class Asctime {

  // ANSI C asctime 関数が出力する日時文字列を解析するフォーマッター
  public static final DateTimeFormatter ASCTIME_DATE_TIME
    = DateTimeFormatter.ofPattern("EEE MMM ppd HH:mm:ss yyyy", new Locale("en", "US"));

  public static void main(String[] args) {

    // asctime 関数が出力する日時文字列と同様のフォーマット文字列を用意
    String[] list = {
      "Sun Nov 18 12:34:56 2007",
      "Sun Dec  1 15:27:08 2019"
    };

    for (String text : list) {
      System.out.println("asctime: " + text);

      // 日時文字列をパースして日時情報に変換
      TemporalAccessor ta = ASCTIME_DATE_TIME.parse(text);
      System.out.println("TemporalAccessor: " + ta);

      LocalDateTime ldt = LocalDateTime.from(ta);
      System.out.println("LocalDateTime: " + ldt);

      // 日本のローカル時間として処理
      ZonedDateTime zdt = ZonedDateTime.of(ldt, ZoneId.of("Asia/Tokyo"));
      System.out.println("ZonedDateTime: " + zdt);

      Instant instant = zdt.toInstant();
      System.out.println("Instant: " + instant);

      Date date = Date.from(instant);
      System.out.println("Date: " + date);

      System.out.println();
    }
  }
}
```

ソースコードをコンパイル。

```
$ javac Asctime.java 
```

実行結果。

```
$ java Asctime
asctime: Sun Nov 18 12:34:56 2007
TemporalAccessor: {},ISO resolved to 2007-11-18T12:34:56
LocalDateTime: 2007-11-18T12:34:56
ZonedDateTime: 2007-11-18T12:34:56+09:00[Asia/Tokyo]
Instant: 2007-11-18T03:34:56Z
Date: Sun Nov 18 12:34:56 JST 2007

asctime: Sun Dec  1 15:27:08 2019
TemporalAccessor: {},ISO resolved to 2019-12-01T15:27:08
LocalDateTime: 2019-12-01T15:27:08
ZonedDateTime: 2019-12-01T15:27:08+09:00[Asia/Tokyo]
Instant: 2019-12-01T06:27:08Z
Date: Sun Dec 01 15:27:08 JST 2019
```

## 参考資料
- [asctime \(The Single UNIX Specification, Version 2\)](https://pubs.opengroup.org/onlinepubs/007908799/xsh/asctime.html)
- [asctime\(\) — 時間から文字ストリングへの変換 \(IBM i 7.3 の資料\)](https://www.ibm.com/support/knowledgecenter/ja/ssw_ibm_i_73/rtref/asctime.htm)
- [DateTimeFormatter \(Java SE 11 & JDK 11 \)](https://docs.oracle.com/javase/jp/11/docs/api/java.base/java/time/format/DateTimeFormatter.html)