Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
## [1.29.3](https://github.com/rodrigogs/whats-reader/compare/v1.29.2...v1.29.3) (2026-03-03)


### Bug Fixes

* add support for YYYY/MM/DD format with 12-hour AM/PM time ([4223d81](https://github.com/rodrigogs/whats-reader/commit/4223d818f2cbc6b3f164001c3dadf4788921fbfe)), closes [#69](https://github.com/rodrigogs/whats-reader/issues/69)

## [1.29.2](https://github.com/rodrigogs/whats-reader/compare/v1.29.1...v1.29.2) (2026-03-03)


Expand Down
40 changes: 28 additions & 12 deletions examples/parser-tests/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,15 @@ This directory contains WhatsApp chat export examples in various formats for tes
- Date format with dashes instead of slashes/dots
- Standard English media indicators

### 6. `yyyy-mm-dd-format-test.txt`
- **Date Format**: `YYYY/MM/DD, HH:MM AM/PM`
- **Example**: `2024/12/01, 10:04 pm`
- **Locale**: Asian format with 12-hour time
- **Features Tested**:
- Year-first format with 12-hour AM/PM time
- Lowercase am/pm variants
- Tests for issue #69

## Supported Date Formats

The parser supports the following date patterns:
Expand All @@ -72,11 +81,16 @@ The parser supports the following date patterns:
- Example: `10-12-24, 14:30`
- Alternative European format

6. **Asian Format**: `YYYY/MM/DD, HH:MM`
6. **Asian Format (24h)**: `YYYY/MM/DD, HH:MM`
- Example: `2024/12/10, 14:30`
- Year-first format (Japan, China, Korea)

7. **Bracketed Format**: `[DD/MM/YY, HH:MM:SS]`
7. **Asian Format (12h)**: `YYYY/MM/DD, HH:MM AM/PM`
- Example: `2024/12/10, 2:30 PM`
- Year-first format with 12-hour time
- Resolves issue #69

8. **Bracketed Format**: `[DD/MM/YY, HH:MM:SS]`
- Example: `[10/12/24, 14:30:45]`
- Some older WhatsApp versions

Expand Down Expand Up @@ -108,16 +122,18 @@ The parser supports the following date patterns:

The parser recognizes media indicators in multiple languages:

- **English**: `<Media omitted>`, `(file attached)`
- **Portuguese**: `<Mídia oculta>`, `(arquivo anexado)`
- **French**: `<Médias omis>`, `(fichier joint)`
- **German**: `<Medien ausgelassen>`, `(Datei angehängt)`
- **Spanish**: `<Archivo omitido>`, `(archivo adjunto)`
- **Italian**: `<Media eliminati>`, `(file allegato)`
- **Dutch**: `<Medien weggelaten>`, `(bestand bijgevoegd)`
- **Japanese**: `<メディアなし>`, `(ファイル添付)`
- **Chinese**: `<媒体省略>`, `(附件)`
- **Russian**: `<Медиа пропущены>`, `(файл прикреплен)`
- **English**: `<Media omitted>`, `(file attached)`, iOS: `<attached:`
- **Portuguese**: `<Mídia oculta>`, `(arquivo anexado)`, iOS: `<anexo:`, `<anexado:`
- **French**: `<Médias omis>`, `(fichier joint)`, iOS: `<pièce jointe`
- **German**: `<Medien ausgelassen>`, `(Datei angehängt)`, iOS: `<Anhang:`, `<angehängt:`
- **Spanish**: `<Archivo omitido>`, `(archivo adjunto)`, iOS: `<adjunto:`
- **Italian**: `<Media eliminati>`, `(file allegato)`, iOS: `<allegato:`
- **Dutch**: `<Medien weggelaten>`, `(bestand bijgevoegd)`, iOS: `<bijgevoegd:`
- **Japanese**: `<メディアなし>`, `(ファイル添付)`, iOS: `<添付ファイル:`
- **Chinese**: `<媒体省略>`, `(附件)`, iOS: `<附件:`
- **Korean**: `<미디어 생략>`, iOS: `<첨부됨:`
- **Russian**: `<Медиа пропущены>`, `(файл прикреплен)`, iOS: `<прикреплено:`
- **Plus 20+ additional iOS languages**: Catalan, Swedish, Norwegian, Danish, Finnish, Irish, Czech, Slovak, Polish, Hungarian, Romanian, Croatian, Turkish, Vietnamese, Indonesian, Malay, Ukrainian, Greek, Arabic, Persian, Urdu, Hebrew, Hindi, Marathi, Gujarati, Thai

## System Message Indicators

Expand Down
4 changes: 4 additions & 0 deletions examples/parser-tests/ios-attached-media-test.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[13/11/2025, 12:25:55 PM] Alice: Hey there
[13/11/2025, 12:26:10 PM] Alice: <attached: 111111-AUDIO-2023-11-11-11-11-11.opus>
[13/11/2025, 12:26:35 PM] Bob: Got it
[13/11/2025, 12:27:00 PM] Bob: <attached: IMG-2025-11-13-12-27-00.jpg>
Comment thread
rodrigogs marked this conversation as resolved.
3 changes: 3 additions & 0 deletions examples/parser-tests/yyyy-mm-dd-format-test.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
2024/12/01, 10:04 pm - Test
2024/12/02, 4:09 pm - John Doe: Hello World
2024/12/03, 2:30 AM - System message
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "whats-reader",
"productName": "WhatsApp Backup Reader",
"version": "1.29.2",
"version": "1.29.3",
"description": "A desktop app to read and visualize WhatsApp chat exports",
"license": "AGPL-3.0",
"author": {
Expand Down
61 changes: 60 additions & 1 deletion src/lib/parser/chat-parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,48 @@ const MEDIA_INDICATORS = [
'<媒体省略>',
'<미디어 생략>',
'<Медиа пропущены>',
// iOS <attached: ...> markers (from WhatsApp Localizable.strings key zQ+5d)
'<attached:', // English
'<Anhang:', // German
'<angehängt:', // German (alt)
'<adjunto:', // Spanish
'<adjunt:', // Catalan
'<allegato:', // Italian
'<anexo:', // Portuguese (PT)
'<anexado:', // Portuguese (BR)
'<pièce jointe', // French (space before colon in some exports)
'<bijgevoegd:', // Dutch
'<bifogat:', // Swedish
'<vedlagt:', // Norwegian
'<vedhæftet:', // Danish
'<liite:', // Finnish
'<ceangailte:', // Irish
'<příloha:', // Czech
'<príloha:', // Slovak
'<załączono:', // Polish
'<csatolva:', // Hungarian
'<atașare:', // Romanian
'<priloženo:', // Croatian/Slovenian
'<eklendi:', // Turkish
'<đính kèm:', // Vietnamese
'<terlampir:', // Indonesian
'<dilampir:', // Malay
'<прикреплено:', // Russian
'<додано:', // Ukrainian
'<επισυνάφθηκε:', // Greek
'<المُرفق:', // Arabic
'<پیوست:', // Persian
'<پیوستہ:', // Urdu
'<מצורף:', // Hebrew
'<अटैच किया गया:', // Hindi
'<संलग्न केले:', // Marathi
'<જોડાયેલ:', // Gujarati
'<แนบ:', // Thai
'<附件:', // Chinese
'<附件:', // Chinese (fullwidth colon)
'<添付ファイル:', // Japanese
'<添付ファイル:', // Japanese (fullwidth colon)
'<첨부됨:', // Korean
'(file attached)',
'(arquivo anexado)',
'(fichier joint)',
Expand Down Expand Up @@ -253,7 +295,24 @@ const DATE_PATTERNS = [
);
},
},
// YYYY/MM/DD, HH:MM - Asian format
// YYYY/MM/DD, HH:MM AM/PM - Asian format with 12-hour time
{
regex:
/^(\d{4})\/(\d{1,2})\/(\d{1,2}),?\s+(\d{1,2}):(\d{2})(?::(\d{2}))?\s*([AP]M)\s*-\s*/i,
parse: (match: RegExpMatchArray) => {
const [, year, month, day, hours, minutes, seconds, ampm] = match;
return parseDateTime(
parseInt(day, 10),
parseInt(month, 10),
parseInt(year, 10),
parseInt(hours, 10),
parseInt(minutes, 10),
seconds ? parseInt(seconds, 10) : 0,
ampm,
);
},
},
// YYYY/MM/DD, HH:MM - Asian format (24-hour)
{
regex:
/^(\d{4})\/(\d{1,2})\/(\d{1,2}),?\s+(\d{1,2}):(\d{2})(?::(\d{2}))?\s*-\s*/,
Expand Down