universal-date-parser 1.0.0

Universal date parser that can parse any date format into standardized output with intelligent format detection
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
# Universal Date Parser - 汎用日付解析ライブラリ

## はじめに

Universal Date Parserは、あらゆる形式の日付を自動的に解析し、標準化された出力に変換する高性能なRustライブラリです。パフォーマンス、信頼性、使いやすさを重視して設計されており、自動フォーマット検出、タイムゾーン対応、多言語バインディングを提供します。

## ライブラリの特徴

### 主要な機能

- **自動フォーマット検出**: 複数の日付フォーマットを自動で認識
- **高性能**: 1回の解析あたり300-600ナノ秒の超高速処理
- **タイムゾーン対応**: 柔軟なタイムゾーン処理オプション
- **多言語対応**: C FFI、WebAssembly、Python対応
- **ゼロコピー**: 可能な限りメモリコピーを避けた効率的な実装
- **曖昧性解決**: 地域固有のフォーマット(MM/DD vs DD/MM)の賢い判定

### サポートする日付フォーマット

#### ISO 8601標準
```rust
// 完全なISO 8601サポート
"2023-12-25T10:30:00Z"          // UTC日時
"2023-12-25T10:30:00+09:00"     // タイムゾーン付き
"2023-12-25"                    // 日付のみ
"20231225T103000Z"              // コンパクト形式
```

#### 地域別フォーマット
```rust
// アメリカ式(月/日/年)
"12/25/2023"    // MM/DD/YYYY

// ヨーロッパ式(日/月/年)
"25/12/2023"    // DD/MM/YYYY

// 日本式
"2023年12月25日"
"2023/12/25"
```

#### Unixタイムスタンプ
```rust
// 秒精度
"1703520645"        // エポックからの秒数

// ミリ秒精度
"1703520645000"     // エポックからのミリ秒数
```

## アーキテクチャ概要

### コアコンポーネント

#### ParsedDate構造体
解析成功後の日付データを表現する基本構造体:

```rust
#[derive(Debug, Clone, PartialEq)]
pub struct ParsedDate {
    pub year: i32,
    pub month: u32,
    pub day: u32,
    pub hour: Option<u32>,
    pub minute: Option<u32>,
    pub second: Option<u32>,
    pub timezone_offset: Option<i32>,
    pub detected_format: String,
}
```

#### UniversalDateParser
設定可能なオプションを持つメイン解析エンジン:

```rust
pub struct UniversalDateParser {
    timezone_mode: TimezoneMode,
    ambiguity_resolver: AmbiguityResolver,
}
```

#### フォーマット検出エンジン
自動パターンマッチングによる賢いフォーマット認識:

```rust
pub fn detect_format(&self, input: &str) -> Option<&'static str> {
    // ISO 8601フォーマット(最優先)
    if ISO_DATETIME_REGEX.is_match(input) {
        return Some("ISO 8601 DateTime");
    }
    
    // Unixタイムスタンプ
    if UNIX_TIMESTAMP_REGEX.is_match(input) {
        return if input.len() > 10 {
            Some("Unix Timestamp (ms)")
        } else {
            Some("Unix Timestamp")
        };
    }
    
    // 地域フォーマットと曖昧性解決
    // ... 高度なパターンマッチング
}
```

### 設計原則

#### パフォーマンス最優先
- 可能な限りゼロコピー解析
- `lazy_static`を使用した効率的な正規表現コンパイル
- 早期リターンによる効率的なパターンマッチング
- ベンチマーク結果:1回の解析あたり300-600ns

#### インテリジェント検出
解析エンジンは以下の優先順位でフォーマットを検出:

1. **ISO 8601標準**(最高優先度)
2. **Unixタイムスタンプ**
3. **明確な地域フォーマット**
4. **曖昧なフォーマットの文脈解決**

#### タイムゾーン対応
柔軟なタイムゾーン処理オプション:

- **AssumeUtc**: すべての日付をUTCとして処理(最高速)
- **AssumeLocal**: システムタイムゾーンを使用
- **PreserveOffset**: 元のタイムゾーン情報を保持
- **ConvertToUtc**: すべての日付をUTCに変換

## インストールと基本的な使用方法

### Cargoプロジェクトへの追加

```toml
[dependencies]
universal-date-parser = "0.1.0"
```

### 基本的な使用例

```rust
use universal_date_parser::{UniversalDateParser, TimezoneMode};

fn main() {
    let parser = UniversalDateParser::new(TimezoneMode::AssumeUtc);
    
    // 様々なフォーマットの解析
    let inputs = vec![
        "2023-12-25T10:30:00Z",
        "12/25/2023",
        "25/12/2023",
        "1703520645",
        "2023年12月25日",
    ];
    
    for input in inputs {
        match parser.parse(input) {
            Ok(parsed) => {
                println!("入力: {} -> 解析結果: {:?}", input, parsed);
                println!("検出されたフォーマット: {}", parsed.detected_format);
            },
            Err(e) => println!("解析エラー: {}", e),
        }
    }
}
```

### 高度な設定例

```rust
use universal_date_parser::{
    UniversalDateParser, 
    TimezoneMode, 
    AmbiguityResolver
};

fn main() {
    // カスタム設定でパーサーを作成
    let parser = UniversalDateParser::builder()
        .timezone_mode(TimezoneMode::PreserveOffset)
        .ambiguity_resolver(AmbiguityResolver::PreferEuropean)
        .build();
    
    // 曖昧な日付の解析
    let ambiguous_date = "01/02/2023";
    match parser.parse(ambiguous_date) {
        Ok(parsed) => {
            // PreferEuropeanの設定により、01/02/2023は2月1日として解釈
            println!("解析結果: {}-{:02}-{:02}", 
                parsed.year, parsed.month, parsed.day);
        },
        Err(e) => println!("エラー: {}", e),
    }
}
```

## パフォーマンス特性

### ベンチマーク結果

Criterionを使用した包括的なベンチマークに基づく結果:

| フォーマットタイプ | 平均時間 | スループット |
|-------------------|----------|--------------|
| ISO 8601 DateTime | 388ns | 2.6M ops/sec |
| ISO 8601 Date | 344ns | 2.9M ops/sec |
| アメリカ式フォーマット | 392ns | 2.6M ops/sec |
| ヨーロッパ式フォーマット | 618ns | 1.6M ops/sec |
| Unixタイムスタンプ | 483ns | 2.1M ops/sec |
| Unixタイムスタンプ(ms) | 598ns | 1.7M ops/sec |

### メモリ使用量
- 最小限のヒープアロケーション
- 静的正規表現パターンの使用
- スタックベースの解析でメモリ効率を最大化

### 最適化手法

#### ゼロコピー解析
```rust
// 文字列のコピーを避けた効率的な解析
pub fn parse_iso_date(&self, input: &str) -> Result<ParsedDate, ParseError> {
    // 直接文字列スライスを操作してパフォーマンス向上
    let year: i32 = input[0..4].parse()?;
    let month: u32 = input[5..7].parse()?;
    let day: u32 = input[8..10].parse()?;
    // ...
}
```

#### 遅延正規表現コンパイル
```rust
lazy_static! {
    static ref ISO_DATETIME_REGEX: Regex = 
        Regex::new(r"^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?(Z|[+-]\d{2}:\d{2})$")
        .unwrap();
}
```

## 多言語バインディング

### C FFI
C言語からの使用例:

```c
#include "universal_date_parser.h"

int main() {
    UniversalDateParser* parser = universal_parser_new();
    
    ParsedDate result;
    int status = universal_parser_parse(parser, "2023-12-25", &result);
    
    if (status == 0) {
        printf("解析成功: %d-%d-%d\n", result.year, result.month, result.day);
    }
    
    universal_parser_free(parser);
    return 0;
}
```

### WebAssembly
JavaScript/TypeScriptからの使用:

```javascript
import { UniversalDateParser } from './pkg/universal_date_parser.js';

const parser = new UniversalDateParser();
const result = parser.parse("2023-12-25T10:30:00Z");

console.log(`解析結果: ${result.year}-${result.month}-${result.day}`);
console.log(`検出フォーマット: ${result.detected_format}`);
```

### Python バインディング
PyO3を使用したPython対応:

```python
import universal_date_parser

parser = universal_date_parser.UniversalDateParser()
result = parser.parse("2023-12-25T10:30:00Z")

print(f"解析結果: {result.year}-{result.month}-{result.day}")
print(f"検出フォーマット: {result.detected_format}")
```

## 実用的な使用例

### ログ解析システム
```rust
use universal_date_parser::{UniversalDateParser, TimezoneMode};
use std::collections::HashMap;

struct LogAnalyzer {
    parser: UniversalDateParser,
    stats: HashMap<String, u32>,
}

impl LogAnalyzer {
    fn new() -> Self {
        Self {
            parser: UniversalDateParser::new(TimezoneMode::AssumeUtc),
            stats: HashMap::new(),
        }
    }
    
    fn analyze_log_entry(&mut self, log_line: &str) {
        // ログエントリから日付部分を抽出
        if let Some(date_part) = self.extract_date_from_log(log_line) {
            match self.parser.parse(&date_part) {
                Ok(parsed) => {
                    let format = parsed.detected_format.clone();
                    *self.stats.entry(format).or_insert(0) += 1;
                },
                Err(_) => {
                    *self.stats.entry("unknown".to_string()).or_insert(0) += 1;
                }
            }
        }
    }
    
    fn extract_date_from_log(&self, log_line: &str) -> Option<String> {
        // ログ形式に応じた日付抽出ロジック
        // 実際の実装では正規表現などを使用
        None
    }
}
```

### データベース移行ツール
```rust
use universal_date_parser::{UniversalDateParser, TimezoneMode};

struct DataMigrator {
    parser: UniversalDateParser,
}

impl DataMigrator {
    fn new() -> Self {
        Self {
            parser: UniversalDateParser::new(TimezoneMode::ConvertToUtc),
        }
    }
    
    fn migrate_date_column(&self, values: Vec<String>) -> Vec<String> {
        values.into_iter()
            .map(|date_str| {
                match self.parser.parse(&date_str) {
                    Ok(parsed) => {
                        // ISO 8601 UTC形式に統一
                        format!("{:04}-{:02}-{:02}T{:02}:{:02}:{:02}Z",
                            parsed.year,
                            parsed.month,
                            parsed.day,
                            parsed.hour.unwrap_or(0),
                            parsed.minute.unwrap_or(0),
                            parsed.second.unwrap_or(0)
                        )
                    },
                    Err(_) => date_str, // 解析失敗時は元の値を保持
                }
            })
            .collect()
    }
}
```

### API レスポンス正規化
```rust
use universal_date_parser::{UniversalDateParser, TimezoneMode};
use serde::{Deserialize, Serialize};

#[derive(Deserialize, Serialize)]
struct ApiResponse {
    id: u64,
    #[serde(deserialize_with = "parse_flexible_date")]
    created_at: String,
    data: serde_json::Value,
}

fn parse_flexible_date<'de, D>(deserializer: D) -> Result<String, D::Error>
where
    D: serde::Deserializer<'de>,
{
    let s = String::deserialize(deserializer)?;
    let parser = UniversalDateParser::new(TimezoneMode::ConvertToUtc);
    
    match parser.parse(&s) {
        Ok(parsed) => Ok(format!("{:04}-{:02}-{:02}T{:02}:{:02}:{:02}Z",
            parsed.year,
            parsed.month,
            parsed.day,
            parsed.hour.unwrap_or(0),
            parsed.minute.unwrap_or(0),
            parsed.second.unwrap_or(0)
        )),
        Err(_) => Err(serde::de::Error::custom("無効な日付フォーマット")),
    }
}
```

## エラーハンドリングとデバッグ

### エラータイプ
```rust
#[derive(Debug, Clone)]
pub enum ParseError {
    InvalidFormat(String),
    InvalidDate(String),
    AmbiguousFormat(String),
    TimezoneParseError(String),
    NumericParseError(String),
}

impl std::fmt::Display for ParseError {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        match self {
            ParseError::InvalidFormat(msg) => write!(f, "無効なフォーマット: {}", msg),
            ParseError::InvalidDate(msg) => write!(f, "無効な日付: {}", msg),
            ParseError::AmbiguousFormat(msg) => write!(f, "曖昧なフォーマット: {}", msg),
            ParseError::TimezoneParseError(msg) => write!(f, "タイムゾーンエラー: {}", msg),
            ParseError::NumericParseError(msg) => write!(f, "数値変換エラー: {}", msg),
        }
    }
}
```

### デバッグモード
```rust
let parser = UniversalDateParser::builder()
    .debug_mode(true)
    .build();

match parser.parse("ambiguous/date/format") {
    Ok(result) => println!("成功: {:?}", result),
    Err(e) => {
        println!("エラー: {}", e);
        // デバッグモードでは詳細な解析ステップが出力される
    }
}
```

## テストとベンチマーク

### 単体テスト例
```rust
#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_iso_8601_parsing() {
        let parser = UniversalDateParser::new(TimezoneMode::AssumeUtc);
        let result = parser.parse("2023-12-25T10:30:00Z").unwrap();
        
        assert_eq!(result.year, 2023);
        assert_eq!(result.month, 12);
        assert_eq!(result.day, 25);
        assert_eq!(result.hour, Some(10));
        assert_eq!(result.minute, Some(30));
        assert_eq!(result.second, Some(0));
    }

    #[test]
    fn test_ambiguous_format_resolution() {
        let parser = UniversalDateParser::builder()
            .ambiguity_resolver(AmbiguityResolver::PreferEuropean)
            .build();
        
        let result = parser.parse("01/02/2023").unwrap();
        assert_eq!(result.month, 2); // ヨーロッパ式:1日2月
        assert_eq!(result.day, 1);
    }
}
```

### パフォーマンステスト
```rust
use criterion::{black_box, criterion_group, criterion_main, Criterion};

fn benchmark_parsing(c: &mut Criterion) {
    let parser = UniversalDateParser::new(TimezoneMode::AssumeUtc);
    
    c.bench_function("ISO 8601 parsing", |b| {
        b.iter(|| parser.parse(black_box("2023-12-25T10:30:00Z")))
    });
    
    c.bench_function("Unix timestamp parsing", |b| {
        b.iter(|| parser.parse(black_box("1703520645")))
    });
}

criterion_group!(benches, benchmark_parsing);
criterion_main!(benches);
```

## よくある質問とトラブルシューティング

### Q: 曖昧な日付フォーマットはどのように処理されますか?

A: ライブラリは以下の戦略で曖昧性を解決します:

1. **文脈分析**: 同じ入力内の他の日付パターンから推測
2. **設定可能な解決方法**: `AmbiguityResolver`で地域設定を指定
3. **エラー報告**: 解決不可能な場合は明確なエラーメッセージ

```rust
// 曖昧性解決の設定例
let parser = UniversalDateParser::builder()
    .ambiguity_resolver(AmbiguityResolver::PreferUS)  // MM/DD/YYYY優先
    .build();
```

### Q: カスタム日付フォーマットを追加できますか?

A: 現在のバージョンではカスタムフォーマットの直接追加はサポートしていませんが、将来のバージョンで実装予定です。回避策として前処理で標準フォーマットに変換してください。

### Q: パフォーマンスを最大化するには?

A: 以下の最適化を推奨します:

1. **適切なタイムゾーンモード**: `AssumeUtc`が最高速
2. **パーサーの再利用**: インスタンス作成コストを削減
3. **バッチ処理**: 大量データの一括処理

```rust
// 最適化された使用例
let parser = UniversalDateParser::new(TimezoneMode::AssumeUtc);
let dates: Vec<&str> = vec![/* 大量の日付文字列 */];

let results: Vec<_> = dates.par_iter()  // rayon使用で並列処理
    .map(|date| parser.parse(date))
    .collect();
```

### Q: メモリ使用量を削減するには?

A: ライブラリは既に最小限のメモリ使用量で設計されていますが、さらに削減するには:

1. **不要な文字列クローンを避ける**
2. **パース結果の即座の処理**
3. **大量データの場合はストリーミング処理**

## 今後の開発予定

### バージョン 0.2.0 (予定)
- **自然言語解析**: "yesterday", "next week"などの相対日付
- **カスタムフォーマット**: ユーザー定義パターンのサポート
- **ローカライゼーション**: 多言語の月名・曜日名対応

### バージョン 0.3.0 (予定)
- **時間範囲解析**: "from 2023-01-01 to 2023-12-31"
- **ファジーマッチング**: 軽微な入力エラーの自動修正
- **パフォーマンス向上**: SIMD命令の活用

### 長期計画
- **機械学習**: AIベースのフォーマット推測
- **プラグインシステム**: サードパーティ拡張のサポート
- **ビジュアルツール**: 解析ルールの可視化

## コントリビューション

### 開発に参加するには

1. **リポジトリのフォーク**
2. **機能ブランチの作成**: `git checkout -b feature/amazing-feature`
3. **変更のコミット**: `git commit -m 'Add amazing feature'`
4. **ブランチのプッシュ**: `git push origin feature/amazing-feature`
5. **プルリクエストの作成**

### コーディングガイドライン

- **Rustfmt**: `cargo fmt`でフォーマット
- **Clippy**: `cargo clippy`で静的解析
- **テスト**: すべての新機能にテストを追加
- **ドキュメント**: パブリックAPIにはドキュメントコメント必須

### バグレポート

バグを発見した場合は、以下の情報を含めてIssueを作成してください:

- **Rustバージョン**
- **ライブラリバージョン**
- **入力データの例**
- **期待される結果**
- **実際の結果**
- **エラーメッセージ**

## まとめ

Universal Date Parserは、Rustエコシステムにおける包括的な日付解析ソリューションです。高性能、柔軟性、使いやすさを兼ね備え、様々なアプリケーションでの日付処理を大幅に簡素化します。

### 主な利点

- **統一されたAPI**: 複数フォーマットを単一インターフェースで処理
- **高性能**: 本番環境で実証済みの速度
- **信頼性**: 包括的なテストスイートによる品質保証
- **拡張性**: 将来の機能追加に対応したアーキテクチャ

### 適用分野

- **ログ解析システム**
- **データ移行ツール**
- **API統合**
- **リアルタイム処理**
- **バッチ処理アプリケーション**

Rustの安全性とパフォーマンスを活用し、日付解析における複雑さを隠蔽しながら、開発者に強力で使いやすいツールを提供します。

---

**プロジェクトリンク**:
- GitHub: https://github.com/rust-core-libs/universal-date-parser
- Crates.io: https://crates.io/crates/universal-date-parser
- ドキュメント: https://docs.rs/universal-date-parser

**ライセンス**: MIT / Apache 2.0 デュアルライセンス