C3 AI Documentation Home

DateTime Format Annotation (Ann.Ser)

The @ser(dateTimeFormat) annotation specifies custom datetime formats for reading and writing data. This ensures consistent and accurate datetime handling regardless of source format. See the Common DateTime Formats table for format examples.

This capability eliminates the need for Transform layers and creates pipelines with better performance, less overhead time, and improved data accuracy.

Note: The @ser annotation should only be used in exceptional cases such as when integrating with external data sources or implementing backwards compatibility layers.

Note: If not specified, the default datetime serialization format will be used. See Default DateTime Serialization Format for more information.

Common dateTime Formats

DescriptionFormatExample
ISO 8601yyyy-MM-dd'T'HH:mm:ss2024-03-15T14:30:45
Date-only format (US style)MM/dd/yyyy03/15/2024
European date with timedd/MM/yyyy HH:mm15/03/2024 14:30
ISO date-only formatyyyy-MM-dd2024-03-15
Time-only formatHH:mm:ss14:30:45

Note: ISO 8601 is the Default DateTime Format.

Key Features

The following are the key features of the dateTime format annotation:

  • Unified Format Control: Format annotations control both schema generation and serialization, ensuring consistency across the entire data pipeline.
  • Intelligent Type Selection: Format annotations inform storage type and precision selection, reducing manual configuration. Ensure the declared field type matches the specified format precision.
  • Automatic dateTime Parsing: SourceCollection.readObjs() natively supports dateTime parsing from strings using format annotations.
  • Bidirectional Format Control: Specify dateTime formats for both reading from sources and writing to outputs. This allows you to generate object lists with different dateTime formats and precision levels for different consumers.

When to Use dateTime Format Annotation (Ann.Ser)

Use this annotation when:

  • Source data has dateTime values in non-standard formats.
  • You need specific timestamp precision for your use case.
    • Example: Use datetime with millis for millisecond formats, datetime with micros for microsecond formats. Ensure your field type matches your format precision.
  • You need to generate outputs in different dateTime formats for different consumers.
  • You need a consistent format for both reading and writing external data.
    • Example: External system uses US format ("MM/dd/yyyy") for both input CSV and output API responses.

Default dateTime Serialization Format

When no @ser(dateTimeFormat="...") annotation is specified, ISO 8601 is used and the exact format automatically matches the field's precision as shown in the table below.

Field TypeDefault FormatExample
datetime (seconds)yyyy-MM-dd'T'HH:mm:ss2023-12-25T14:30:45
datetime with millisyyyy-MM-dd'T'HH:mm:ss.SSS2023-12-25T14:30:45.123
datetime with microsyyyy-MM-dd'T'HH:mm:ss.SSSSSS2023-12-25T14:30:45.123456

Note: Microsecond precision support added in version 8.10

Note: The field type precision must match your format annotation. See the example in Precision Mismatch for more details.

Example for Default dateTime Format

This example shows three dateTime fields, each with different precision levels. When serialized to JSON without any format annotations, each field automatically uses the ISO 8601 format matching its declared precision.

Type
type Example { 
   EventTimeSec: datetime                // No annotation 
   EventTimeMillis: datetime with millis // No annotation 
   EventTimeMicros: datetime with micros // No annotation 
} 

Serialized JSON (default):

JavaScript
{  
 "EventTimeSec": "2023-12-25T14:30:45",             // outputs date and time only
 "EventTimeMillis": "2023-12-25T14:30:45.123",      // the milliseconds field adds three decimal places
 "EventTimeMicros": "2023-12-25T14:30:45.123456"    // the microseconds field adds six decimal places
}  

Example 1: API with Standard DateTime Format

Entity Type:

Type
entity type SensorReading { 

  sensor_id: string 

// The dateTimeFormat="yyyy-MM-dd HH:mm:ss" guides the serializer to format the DateTime
// DateTime is formatted without milliseconds or timezone indicators. 

  @ser(dateTimeFormat="yyyy-MM-dd HH:mm:ss") 
  reading_time: datetime 
  temperature: double 
} 

Create and Serialize:

JavaScript
var reading = SensorReading.make({ 

  sensor_id: "SENSOR-001", 
  reading_time: DateTime.now(), 
  temperature: 72.5 

}); 

// Serialize to JSON 
var json = reading.toJson(); 
console.log(json); 

JSON Output:

JSON
{ 
  "sensor_id": "SENSOR-001", 
  "reading_time": "2024-01-15 14:30:00", 
  "temperature": 72.5 
} 

Example 2: Date-Only Format

Entity Type:

JavaScript
entity type Employee { 

  employee_id: string 
  name: string 

// The dateTimeFormat="MM/dd/yyyy" serializes DateTime as US-style date-only format (MM/dd/yyyy)
// Useful for reports targeting US audiences

  @ser(dateTimeFormat="MM/dd/yyyy") 
  birth_date: datetime 
  @ser(dateTimeFormat="MM/dd/yyyy") 
  hire_date: datetime 
} 

Fetch and Export:

JavaScript
var employees = Employee.fetch({limit: 100}); 

// Export to CSV with custom date format 
employees.objs.forEach(function(emp) { 
  var json = emp.toJson(); 
  console.log(json); 
}); 

JSON Output:

JSON
{ 
  "employee_id": "EMP001", 
  "name": "John Doe", 
  "birth_date": "03/15/1985", 
  "hire_date": "06/01/2010" 
} 

Example 3: Microsecond Precision Format

Entity Type:

JavaScript
entity type HighPrecisionEvent mixes Source {
  name: string
  
// Captures microsecond precision for high-frequency events
// Supported in version 8.10+
  @ser(dateTimeFormat="yyyy-MM-dd'T'HH:mm:ss.SSSSSS'Z'")
  timestamp: datetime with micros // Matches format precision
}

Source File:

JSON
{
  "name": "SensorEvent001",
  "timestamp": "2025-10-15T14:23:45.123456Z"
}

Create and Serialize

JavaScript
var event = HighPrecisionEvent.make({
  name: "SensorEvent001",
  timestamp: DateTime.nowWithMicros()
});

var json = event.toJson();
console.log(json);

JSON Output:

JSON
{
  "name": "SensorEvent001",
  "timestamp": "2025-10-15T14:23:45.123456Z"
}

Common Issues and Solutions

This section addresses common issues you may encounter when working with dateTime format annotations.

Precision Mismatch

Problem: Milliseconds or microseconds are being truncated or lost. Cause: The format annotation specifies higher precision than the field type supports. Solution: Match your field type to your format precision:

Format PatternRequired Field Type
yyyy-MM-dd or MM/dd/yyyydatetime
yyyy-MM-dd HH:mm:ssdatetime
yyyy-MM-dd'T'HH:mm:ss.SSS'Z'datetime with millis
yyyy-MM-dd'T'HH:mm:ss.SSSSSS'Z'datetime with micros

Note: If you use a format with a specific precision (such as milliseconds: yyyy-MM-dd'T'HH:mm:ss.SSS) but declare the field as datetime instead of datetime with millis, the millisecond precision will be lost. Always ensure the C3 field type precision matches the format you specify.

Example:

Type
// INCORRECT: Field type `datetime` cannot store millisecond precision — milliseconds will be lost.
@ser(dateTimeFormat="yyyy-MM-dd'T'HH:mm:ss.SSS'Z'")
timestamp: datetime

// CORRECT: Precision is preserved when you use `datetime with millis`.
@ser(dateTimeFormat="yyyy-MM-dd'T'HH:mm:ss.SSS'Z'")
timestamp: datetime with millis

Missing Format Annotation for Non-ISO Formats

Problem: Data ingestion fails with parsing errors for DateTime fields. Cause: Source data uses non-ISO 8601 format, but no @ser(dateTimeFormat) annotation is specified. Solution: Always add format annotations when source data does not use the default ISO 8601 format.

Note: When reading data from external sources (CSV, Parquet, APIs), always verify the DateTime format in the source data and add the appropriate @ser(dateTimeFormat) annotation if it differs from ISO 8601.

Example:

Source Data

JavaScript
employee_id,hire_date
// The date format in the source is MM/DD/YYYY, which is not ISO 8601
EMP001,03/15/2020
EMP002,07/22/2021

Source Type

Type
// INCORRECT: Missing format annotation — parsing will fail for non-ISO dates.
type EmployeeSource mixes Source {
  employee_id: string
  hire_date: datetime
}


// CORRECT: Format matches source data
type EmployeeSource mixes Source {
  employee_id: string
  @ser(dateTimeFormat="MM/dd/yyyy")
  hire_date: datetime
}

See also

Was this page helpful?