Concepts / Date and Time Formatting with the time Module

Date and Time Formatting with the time Module

The central idea is to turn the current date and time into a predictable filename, then place that filename into a zip command executed by the operating system.

  • Programming

Why Timestamped Backups Matter

Manually backing up files is tedious and error-prone. You might forget a directory, overwrite an earlier backup, or use an inconsistent filename. A Python backup program automates the process by selecting source directories, creating an archive name based on the current date and time, and executing the backup command.

Key point

The central idea is to turn the current date and time into a predictable filename, then place that filename into a zip command executed by the operating system.

What do you think happens?

What should happen when the backup program runs?

  • It only prints a filename and does not create an archive

  • It prints the command, executes it, and reports success or failure

  • It always reports success without checking the command

  • It creates an archive with the same name every time

Reveal answer
Answer:

It prints the command, executes it, and reports success or failure.

The program constructs a zip command, displays the command it is about to execute, passes it to os.system(), and checks the returned value. A return value of 0 indicates success; a non-zero value indicates failure.

From Clock to Archive Name

The time.strftime() function converts the current date and time into a formatted string. The format string %Y%m%d%H%M%S contains codes for the year, month, day, hour, minute, and second. When those codes are replaced with the current values, the result can be used as part of the archive filename.

CodeMeaning
%YYear
%mMonth
%dDay
%HHour
%MMinute
%SSecond

Format codes used to build the timestamp string described in the source.

python
Output
A possible output is a timestamp such as 20240115143022. The exact value depends on when the program runs.
Current date andtimetime.strftime()%Y%m%d%H%M%S20240115143022formatted timestampbackup/20240115143022.ziparchive filenameformatproduceembed
How does the current date and time become a formatted timestamp embedded in the zip filename?

Portable Backup Paths

A path combines a directory with a filename. The directory separator is not written the same way on every operating system: Windows uses a backslash, while macOS and Linux use a forward slash. Python provides os.sep as the separator appropriate for the operating system where the program is running.

python

The construction pattern is the same on every supported operating system: target directory, os.sep, timestamp, and the .zip extension. The visible separator changes with the operating system, but the backup program keeps the same overall behavior.

Windowsbackup\20240115143022.zipTimestamped ziparchivesame backup behaviormacOSbackup/20240115143022.zipLinuxbackup/20240115143022.zipconstruct pathconstruct pathconstruct path
How does os.sep change the constructed path on Windows, macOS, and Linux while preserving the same backup behavior?

Constructing the Zip Command

The program builds the zip command as a string. It combines the zip utility, the recursive option, the target archive filename, and the source directories. The -r option tells zip to work recursively through subdirectories.

python
Worked example

Joining Source Directories

Suppose source contains two entries: /home/user/docs and /home/user/photos. What string does ' '.join(source) create?

  1. 1
    Start with the list

    The list contains the two source directory paths as separate items.

  2. 2
    Join with a space

    The join() method places one space between the list items and produces one command-ready string.

  3. 3
    Insert into the command

    The resulting string is used as the source portion of the zip command.

Result

'/home/user/docs /home/user/photos'

Python programbuild commandos.system()execute command stringOperating systemshellreceive commandzip-r archive sourcesTimestamped archive.zip filepass command stringexecuteruncreate
How does control and data move from the Python backup program through os.system() to the shell, zip command, and final archive?

Checking the Command Result

os.system() executes the command as if it had been typed into a terminal or command prompt. After the command finishes, os.system() returns a value. A return value of 0 means the command succeeded. A non-zero value means it failed. The program uses this result to choose a success or failure message.

python
os.system(command)run shell commandReturn value0 or non-zeroBackup succeededBackup failedfinish0non-zero
What happens after the shell command finishes, and how does its return value indicate whether the backup command succeeded or failed?

Complete Backup Flow

The following is a generated implementation assembled from the source-described steps. It selects source directories, formats a timestamp, constructs the target path with os.sep, joins the source list, builds the zip command, executes it, and checks the return value.

Code walkthrough
import os
import time

source = ['docs', 'photos']
target_dir = 'backup'

timestamp = time.strftime('%Y%m%d%H%M%S')
target = target_dir + os.sep + timestamp + '.zip'
source_list = ' '.join(source)
command = 'zip -r {0} {1}'.format(target, source_list)

print(command)
result = os.system(command)

if result == 0:
    print('Backup succeeded')
else:
    print('Backup failed')
  1. 1
    The timestamp supplies the archive's time-based name.
  2. 2
    os.sep keeps the path construction aligned with the operating system.
  3. 3
    The command receives the target archive followed by the source directories.
  4. 4
    os.system() passes the command to the shell.
  5. 5
    The conditional verifies the command result instead of assuming that the archive was created.
  • Import os for os.sep and os.system().
  • Import time for time.strftime().
  • Store the directories to include in the backup.
  • Store the directory where the archive will be created.
  • Format the current date and time as year, month, day, hour, minute, and second.
  • Construct the archive path with the operating system's separator.
  • Convert the source list into one space-separated string.
  • Build the recursive zip command.
  • Display the command before executing it.
  • Execute the command and store the returned value.
  • A return value of 0 selects the success message.
  • A non-zero return value selects the failure message.
Worked example

Tracing Concrete Values

Trace the program on a Linux system when target_dir is /home/user/backups, source contains /home/user/docs and /home/user/photos, and the formatted timestamp is 20240115143022.

  1. 1
    Format the timestamp

    time.strftime() produces 20240115143022.

  2. 2
    Construct the target

    Linux uses a forward slash, so the target becomes /home/user/backups/20240115143022.zip.

  3. 3
    Join the sources

    The source list becomes /home/user/docs /home/user/photos.

  4. 4
    Build the command

    The command becomes zip -r /home/user/backups/20240115143022.zip /home/user/docs /home/user/photos.

  5. 5
    Execute and inspect

    os.system() executes the command. If it returns 0, the program prints the success message; otherwise it prints the failure message.

Result

The program sends a timestamped recursive zip command to the shell and reports the result returned by os.system().

Mistakes to Avoid

  • Common mistake

    Hardcoding one directory separator

    What it looks like
    target = target_dir + '/' + timestamp + '.zip'
    Why it fails

    The source emphasizes that Windows uses a backslash while macOS and Linux use a forward slash.

    Do this instead
    Use target_dir + os.sep + timestamp + '.zip'.
  • Common mistake

    Using a fixed archive name

    What it looks like
    target = target_dir + os.sep + 'backup.zip'
    Why it fails

    A fixed name can overwrite an earlier backup instead of preserving timestamped archives.

    Do this instead

    Include the string returned by time.strftime() in the filename.

  • Common mistake

    Passing the source list directly into the command

    What it looks like
    command = 'zip -r {0} {1}'.format(target, source)
    Why it fails

    The source list needs to become a space-separated string for the command.

    Do this instead

    Create source_list with ' '.join(source), then insert source_list into the command.

  • Common mistake

    Assuming the command succeeded

    What it looks like
    os.system(command)
    print('Backup succeeded')
    Why it fails

    The program should use the return value from os.system() to distinguish success from failure.

    Do this instead

    Store the return value and compare it with 0.

  • Common mistake

    Running without customizing paths

    What it looks like

    Using the example source and target_dir values unchanged.

    Why it fails

    The source instructs you to customize source and target_dir for your own system.

    Do this instead

    Choose source directories and a target directory that exist on the system where the program will run.

Practice the Trace

MEDIUM

Assume timestamp is 20251231115959, target_dir is archive, and source is ['work', 'notes']. Write the target path, the joined source string, and the complete zip command. Then state which message the program prints when os.system() returns 0.

Hints
  • Build the target from target_dir, os.sep, timestamp, and .zip.
  • Use a single space between the two source entries.
  • The command begins with zip -r.
  • A return value of 0 selects the success branch.

What do you think happens?

If the command returns a non-zero value, which branch should run?

  • The success branch

  • The failure branch

  • Both branches

  • Neither branch

Reveal answer
Answer:

The failure branch.

The program treats 0 as success and any non-zero return value as failure.

Practical Design Lessons

This backup program separates responsibilities. Python handles file selection, timestamped naming, path construction, command construction, and result checking. The zip utility handles the actual recursive compression. This division lets the program use an established operating-system tool rather than implementing compression itself.

Key point

A useful automation script does more than start an operation. It prepares clear inputs, uses portable system details, executes the operation, and verifies the result.

Key Takeaways

  • time.strftime('%Y%m%d%H%M%S') converts the current date and time into a timestamp suitable for an archive filename.
  • os.sep supplies the operating system's directory separator instead of forcing one separator into the program.
  • The zip command is built from the recursive option, target archive path, and a space-separated source list.
  • os.system() passes the command to the shell and returns 0 for success or a non-zero value for failure.
  • A complete backup flow constructs the archive name, builds the command, executes it, and checks the result.

Related concepts

More concepts starting with D