Optimal Timestamp Formatting in Filenames: Best Practices for Unix/Linux Systems


3 views

Every sysadmin and developer who's worked with log files, backups, or any time-sensitive data has faced this dilemma: how to properly format timestamps in filenames. While Unix systems technically allow almost any character (except '/' and '\0'), practical considerations force us to be more restrictive.

Consider this common scenario:

# Problematic example with spaces and colons
backup 2023-12-25 23:59:59 EST.tar.gz

# This would break in most scripts:
tar -xzf backup 2023-12-25 23:59:59 EST.tar.gz

1. Syslog-style Format

Example generation in bash:

filename="app-$(date +%Y%m%d%H%M%S).log"
# Result: app-20231225235959.log

This format is excellent for sorting and scripting but hard to read at a glance.

2. ISO-8601 Variants

Basic date-only version:

filename="data-$(date --iso-8601).csv"
# Result: data-2023-12-25.csv

Full timestamp with timezone:

filename="export-$(date --iso-8601=seconds).json"
# Result: export-2023-12-25T23:59:59-05:00.json

3. Hybrid Approaches

When you need readability and script-friendliness:

filename="archive_$(date +%Y-%m-%d_%H-%M-%S).tgz"
# Result: archive_2023-12-25_23-59-59.tgz

For distributed systems, always include timezone information. Here's a Python example:

from datetime import datetime
timestamp = datetime.now().astimezone().strftime("%Y%m%d-%H%M%S%z")
filename = f"cluster-{timestamp}.dump"
# Result: cluster-20231226-045959-0500.dump
  • For local logs: Use %Y%m%d or %Y%m%d%H%M
  • For distributed systems: Always include timezone (%z)
  • For human-readable files: Consider underscores instead of colons
# Basic date
date +%Y%m%d

# Date and time (no TZ)
date +%Y%m%d%H%M%S

# ISO-8601 with TZ (UTC)
date -u +%Y-%m-%dT%H:%M:%SZ

# Custom readable format
date +"%Y-%m-%d_%H-%M-%S_%Z"

The "best" format depends on your specific use case. For maximum compatibility across tools and systems, I recommend the hybrid approach with underscores:

service-2023-12-26_04-59-59_EST.log

This format avoids problematic characters while remaining reasonably human-readable.


Any sysadmin or developer who's worked with log files, backups, or automated reports knows the pain of timestamp formatting in filenames. While Unix technically allows almost any character except '/' and null bytes, reality imposes stricter requirements due to toolchain limitations.

Let's examine the most prevalent timestamp formats with concrete examples:

// Traditional syslog/logrotate format
app-log-20230719.log
backup-202307191425.tar.gz

This approach wins on compatibility but loses on readability, especially with time components included.

The ISO 8601 standard provides excellent machine and human readability:

// Basic date format
data-export-2023-07-19.csv

// Full timestamp with timezone
error-2023-07-19T14:25:00-0400.log

For shell scripting with date command:

#!/bin/bash
timestamp=$(date --iso-8601=seconds)
filename="backup-${timestamp}.tar.gz"

When dealing with tools that choke on colons (scp, tar, etc.), consider these alternatives:

// Replace colons with hyphens
report-2023-07-19T14-25-00Z.json

// Or use period separators
archive.2023-07-19.142500.tgz

For systems operating across timezones, always include offset information:

// With explicit timezone
transactions-20230719-1425-0400.dat

// UTC indicator
audit-20230719T1425Z.log

Local system logs: appname-YYYYMMDD.log
Cross-system backups: backup-YYYY-MM-DDTHHMMZ.tgz
Human-readable reports: report_YYYY-MM-DD_HH-MM.pdf

Python:

from datetime import datetime
timestamp = datetime.now().strftime("%Y-%m-%dT%H-%M-%S")
filename = f"output-{timestamp}.csv"

JavaScript:

const now = new Date();
const timestamp = now.toISOString().replace(/[:.]/g, '-');
const filename = log-${timestamp.slice(0, -5)}Z.txt;

Lexicographical order should match chronological order. The YYYYMMDD format ensures this naturally:

// Correct sorting
backup-20230101.tgz
backup-20230102.tgz
backup-20230103.tgz

// Problematic sorting (avoid!)
backup-Jan-1-2023.tgz
backup-Jan-10-2023.tgz
backup-Jan-2-2023.tgz