datetime
string formatting
milliseconds
programming
date manipulation

Format a datetime into a string with milliseconds

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Formatting a date-time with milliseconds is common in logs, APIs, filenames, and event auditing. The easy mistake is to focus only on the format token and forget that a useful timestamp also needs a clear precision policy and a clear time-zone policy.

Decide on the Target Shape First

Before writing code, define the exact output you want. Two common formats are:

  • '2026-03-11 14:05:09.123'
  • '2026-03-11T14:05:09.123Z'

The second is usually better for APIs because it follows ISO 8601 style and carries UTC context. The first is readable for humans, but by itself it does not say whether the time is local time or UTC.

That choice matters more than the milliseconds themselves. A precise timestamp with no zone information is still ambiguous once it moves between systems.

Python Example

In Python, strftime uses %f for microseconds, so trimming to three digits is the usual way to format milliseconds.

python
1from datetime import datetime, timezone
2
3now = datetime.now(timezone.utc)
4text = now.strftime("%Y-%m-%d %H:%M:%S.%f")[:-3]
5print(text)

If an ISO-style string is acceptable, Python can express the same intent more clearly:

python
1from datetime import datetime, timezone
2
3now = datetime.now(timezone.utc)
4print(now.isoformat(timespec="milliseconds"))

That version is often a better default because the output is standardized and includes offset information.

Java Example

Modern Java code should use java.time and the SSS pattern token for milliseconds.

java
1import java.time.Instant;
2import java.time.ZoneOffset;
3import java.time.format.DateTimeFormatter;
4
5public class Main {
6    public static void main(String[] args) {
7        DateTimeFormatter formatter = DateTimeFormatter
8            .ofPattern("yyyy-MM-dd HH:mm:ss.SSS")
9            .withZone(ZoneOffset.UTC);
10
11        String text = formatter.format(Instant.now());
12        System.out.println(text);
13    }
14}

Using Instant plus an explicit zone makes the code's intent clear. Without that zone decision, readers have to guess whether the output is local time.

C# Example

In .NET, fff is the millisecond token.

csharp
1using System;
2using System.Globalization;
3
4DateTimeOffset now = DateTimeOffset.UtcNow;
5string text = now.ToString("yyyy-MM-dd HH:mm:ss.fff", CultureInfo.InvariantCulture);
6Console.WriteLine(text);

CultureInfo.InvariantCulture is a good choice for logs and machine-readable files because it avoids localization side effects in separators and formatting.

JavaScript Example

JavaScript Date stores milliseconds already. If ISO output is acceptable, toISOString() is usually the simplest answer.

javascript
console.log(new Date().toISOString());

If you need a custom layout, format the parts explicitly:

javascript
1const now = new Date();
2const yyyy = now.getUTCFullYear();
3const mm = String(now.getUTCMonth() + 1).padStart(2, "0");
4const dd = String(now.getUTCDate()).padStart(2, "0");
5const hh = String(now.getUTCHours()).padStart(2, "0");
6const mi = String(now.getUTCMinutes()).padStart(2, "0");
7const ss = String(now.getUTCSeconds()).padStart(2, "0");
8const ms = String(now.getUTCMilliseconds()).padStart(3, "0");
9
10console.log(`${yyyy}-${mm}-${dd} ${hh}:${mi}:${ss}.${ms}`);

Here UTC accessors are used deliberately so the output has one stable time-zone policy.

Precision and Round-Tripping

Milliseconds are only one precision level. Some platforms store microseconds or nanoseconds internally and then truncate during formatting. That is fine if the contract says milliseconds, but it should be intentional.

If another system will parse the string later, consistency matters more than cosmetic readability. A stable, round-trippable format with explicit zone handling is easier to debug than a pretty local-time string that changes meaning across machines.

For distributed systems, UTC is usually the safest default. For end-user display, local time may be correct, but then the UI should make that context clear.

Common Pitfalls

  • Choosing a format string before deciding whether the timestamp should be local time or UTC.
  • Confusing microseconds and milliseconds, especially in Python.
  • Using legacy date APIs when modern immutable APIs are available.
  • Emitting localized or machine-unstable output for logs and integration points.
  • Serializing to string too early in the pipeline and repeatedly reparsing the same timestamp.

Summary

  • Formatting with milliseconds also requires clear precision and time-zone choices.
  • Python, Java, C#, and JavaScript all support millisecond output, but the tokens differ.
  • Prefer standardized UTC output for logs and APIs when possible.
  • Use modern date-time libraries such as java.time and DateTimeOffset.
  • Keep the format stable if another system will parse the timestamp later.

Course illustration
Course illustration

All Rights Reserved.