Date and Time Functions
Date and time functions provide operations for formatting dates and calculating time differences.
Function Reference
Section titled “Function Reference”formatdate
Section titled “formatdate”Formats a timestamp according to a specification string.
formatdate(spec, timestamp)Parameters:
- spec- Format specification string
- timestamp- RFC 3339 timestamp string
Returns: Formatted date string
Format Specifiers:
- YYYY- 4-digit year
- YY- 2-digit year
- MM- 2-digit month (01-12)
- MMM- Abbreviated month name
- MMMM- Full month name
- DD- 2-digit day (01-31)
- HH- 2-digit hour (00-23)
- hh- 2-digit hour (01-12)
- mm- 2-digit minute (00-59)
- ss- 2-digit second (00-59)
- AA- AM/PM
Example:
formatdate("YYYY-MM-DD", "2024-01-15T10:30:00Z")        # Returns: "2024-01-15"formatdate("DD MMM YYYY", "2024-01-15T10:30:00Z")       # Returns: "15 Jan 2024"formatdate("hh:mm AA", "2024-01-15T14:30:00Z")          # Returns: "02:30 PM"formatdate("YYYY-MM-DD HH:mm:ss", "2024-01-15T10:30:45Z") # Returns: "2024-01-15 10:30:45"timeadd
Section titled “timeadd”Adds a duration to a timestamp.
timeadd(timestamp, duration)Parameters:
- timestamp- RFC 3339 timestamp string
- duration- Duration string (e.g., “1h”, “30m”, “2h30m”)
Returns: New timestamp after adding duration
Duration Units:
- h- hours
- m- minutes
- s- seconds
Example:
timeadd("2024-01-15T10:00:00Z", "1h")         # Returns: "2024-01-15T11:00:00Z"timeadd("2024-01-15T10:00:00Z", "30m")        # Returns: "2024-01-15T10:30:00Z"timeadd("2024-01-15T10:00:00Z", "2h30m")      # Returns: "2024-01-15T12:30:00Z"timeadd("2024-01-15T10:00:00Z", "-1h")        # Returns: "2024-01-15T09:00:00Z"Common Use Cases
Section titled “Common Use Cases”Resource Naming with Timestamps
Section titled “Resource Naming with Timestamps”variable "created_at" {  default = "2024-01-15T10:30:00Z"}
locals {  # Create readable names with timestamps  backup_name = "backup-${formatdate("YYYY-MM-DD-HHmmss", var.created_at)}"  snapshot_id = "snap-${formatdate("YYYYMMDD", var.created_at)}"
  # Daily rotation names  log_file = "app-${formatdate("YYYY-MM-DD", var.created_at)}.log"}
resource "container" "app" {  container_name = "app-${formatdate("YYYYMMDDHHmmss", var.created_at)}"
  labels = {    created_at = var.created_at    expires_at = timeadd(var.created_at, "24h")  }}Scheduled Operations
Section titled “Scheduled Operations”variable "maintenance_start" {  default = "2024-01-15T02:00:00Z"}
locals {  # Calculate future times  maintenance_end = timeadd(var.maintenance_start, "30m")
  # Next day at same time  next_maintenance = timeadd(var.maintenance_start, "24h")}
resource "template" "schedule" {  source = <<-EOF    Maintenance Window:    Start: ${formatdate("YYYY-MM-DD hh:mm AA", var.maintenance_start)}    End: ${formatdate("YYYY-MM-DD hh:mm AA", local.maintenance_end)}    Duration: 30 minutes    Next: ${formatdate("YYYY-MM-DD hh:mm AA", local.next_maintenance)}  EOF
  destination = "./maintenance-schedule.txt"}Log Rotation
Section titled “Log Rotation”variable "log_timestamp" {  default = "2024-01-15T10:00:00Z"}
locals {  # Generate time-based paths  log_dir = "./logs/${formatdate("YYYY/MM", var.log_timestamp)}"  log_file = "${local.log_dir}/app-${formatdate("DD", var.log_timestamp)}.log"
  # Archive naming for previous month  archive_date = timeadd(var.log_timestamp, "-720h")  # 30 days ago  archive_name = "logs-${formatdate("YYYY-MM", local.archive_date)}.tar.gz"}Expiration Handling
Section titled “Expiration Handling”variable "retention_hours" {  default = 168  # 7 days}
variable "created_at" {  default = "2024-01-15T10:00:00Z"}
locals {  # Calculate expiration  expires_at = timeadd(var.created_at, "${var.retention_hours}h")
  # Human-readable expiration  expiry_date = formatdate("MMMM DD, YYYY", local.expires_at)}
resource "template" "metadata" {  source = jsonencode({    created = var.created_at    expires = local.expires_at    expires_human = "This resource expires on ${local.expiry_date}"    retention_hours = var.retention_hours  })
  destination = "./metadata.json"}Backup Scheduling
Section titled “Backup Scheduling”variable "backup_time" {  default = "2024-01-15T03:00:00Z"}
locals {  # Daily backup times  daily_backup = formatdate("YYYY-MM-DD", var.backup_time)  weekly_backup = formatdate("YYYY-'W'ww", var.backup_time)  monthly_backup = formatdate("YYYY-MM", var.backup_time)
  # Calculate next backup times  next_daily = timeadd(var.backup_time, "24h")  next_weekly = timeadd(var.backup_time, "168h")  # 7 days}
resource "exec" "backup" {  command = "backup.sh"  arguments = [    "--daily", local.daily_backup,    "--weekly", local.weekly_backup,    "--monthly", local.monthly_backup  ]
  environment = {    BACKUP_TIME = var.backup_time    BACKUP_ID = formatdate("YYYYMMDDHHmmss", var.backup_time)    NEXT_BACKUP = local.next_daily  }}Duration Calculations
Section titled “Duration Calculations”variable "task_start" {  default = "2024-01-15T09:00:00Z"}
variable "task_duration_minutes" {  default = 45}
locals {  end_time = timeadd(var.task_start, "${var.task_duration_minutes}m")
  # Create a schedule entry  schedule_entry = {    task = "lab-exercise"    start = formatdate("hh:mm AA", var.task_start)    end = formatdate("hh:mm AA", local.end_time)    duration = "${var.task_duration_minutes} minutes"    date = formatdate("YYYY-MM-DD", var.task_start)  }}
resource "template" "schedule" {  source = jsonencode(local.schedule_entry)  destination = "./task-schedule.json"}Multi-timezone Formatting
Section titled “Multi-timezone Formatting”variable "utc_time" {  default = "2024-01-15T14:30:00Z"}
locals {  # Format for different contexts (all times are UTC)  iso_date = formatdate("YYYY-MM-DD", var.utc_time)  human_readable = formatdate("MMM DD, YYYY at hh:mm AA", var.utc_time)  filename_safe = formatdate("YYYY-MM-DD_HH-mm-ss", var.utc_time)  log_format = formatdate("YYYY-MM-DD HH:mm:ss", var.utc_time)}
resource "template" "timestamps" {  source = <<-EOF    Event Timestamps (UTC):    ISO Format: ${local.iso_date}    Human Readable: ${local.human_readable}    Filename Safe: ${local.filename_safe}    Log Format: ${local.log_format}  EOF
  destination = "./timestamps.txt"}Best Practices
Section titled “Best Practices”- 
Use Consistent Formats: Standardize date formats across your lab locals {# Define standard formatsdate_format = "YYYY-MM-DD"time_format = "HH:mm:ss"datetime_format = "${local.date_format} ${local.time_format}"}
- 
Always Use UTC: All timestamps should be in UTC (RFC 3339 format) locals {# Document timezone assumptionsevent_time = "2024-01-15T10:30:00Z" # UTC# Note: All times are in UTC}
- 
Validate Time Inputs: Ensure timestamps are properly formatted variable "start_date" {type = stringvalidation {condition = can(formatdate("YYYY", var.start_date))error_message = "start_date must be a valid RFC 3339 timestamp"}}
- 
Use Meaningful Names: Make time-based resources clear locals {# Clear naming for time-based resourcesdaily_report = "report-${formatdate("YYYY-MM-DD", var.report_time)}"hourly_backup = "backup-${formatdate("YYYY-MM-DD-HH", var.backup_time)}"}
