DateTime Models
DateTime models provide standardized date, time, and duration representations used throughout DDEX messages for release dates, licensing periods, and temporal metadata.
Core Types
EventDate
Represents dates with varying precision levels:
interface EventDate {
date: string; // ISO 8601 format
precision?: DatePrecision;
isApproximate?: boolean;
territoryCode?: string; // Territory-specific dates
}
enum DatePrecision {
Year = 'Year',
Month = 'Month',
Day = 'Day',
Hour = 'Hour',
Minute = 'Minute',
Second = 'Second'
}
Duration
Represents time durations in ISO 8601 format:
interface Duration {
value: string; // e.g., "PT3M45S" for 3 minutes 45 seconds
}
Period
Represents time periods with start and end boundaries:
interface Period {
startDate?: EventDate | string;
endDate?: EventDate | string;
duration?: Duration;
isOpenEnded?: boolean;
}
Date Formats
ISO 8601 Format
All dates follow ISO 8601 standard:
// Full precision
"2024-03-15T14:30:00Z" // UTC with seconds
"2024-03-15T14:30:00-05:00" // With timezone offset
// Reduced precision
"2024-03-15" // Date only
"2024-03" // Month only
"2024" // Year only
Duration Format
Durations use ISO 8601 period notation:
"PT3M45S" // 3 minutes 45 seconds
"PT1H30M" // 1 hour 30 minutes
"P1Y2M3DT4H5M6S" // 1 year, 2 months, 3 days, 4 hours, 5 minutes, 6 seconds
Common Use Cases
Release Dates
interface Release {
releaseDate: EventDate;
originalReleaseDate?: EventDate;
pLineDate?: EventDate;
cLineDate?: EventDate;
}
// Example release date
const releaseDate: EventDate = {
date: "2024-03-15",
precision: "Day",
isApproximate: false
};
Licensing Periods
interface Deal {
validityPeriod?: Period;
commercialModelType: CommercialModelType[];
}
// Example licensing period
const licensePeriod: Period = {
startDate: "2024-01-01T00:00:00Z",
endDate: "2025-12-31T23:59:59Z",
isOpenEnded: false
};
Content Duration
interface SoundRecording {
duration?: Duration;
technicalDetails?: {
duration?: Duration;
previewStartTime?: Duration;
previewDuration?: Duration;
};
}
// Example audio duration
const trackDuration: Duration = {
value: "PT3M45S" // 3:45
};
Usage Examples
Parsing Dates
const result = await parser.parse(xmlContent);
// Access release dates
const release = result.flat.releases[0];
console.log('Release date:', release.releaseDate.date);
// Check date precision
if (release.releaseDate.precision === 'Year') {
console.log('Year-only release date');
}
// Territory-specific dates
const usReleaseDate = release.releaseInformation
.find(info => info.territories?.some(t => t.code === 'US'))
?.salesStartDate;
Building Date Data
const buildRequest = {
releases: [{
releaseId: 'R123456789',
releaseDate: {
date: '2024-03-15',
precision: 'Day',
isApproximate: false
},
originalReleaseDate: {
date: '2023',
precision: 'Year',
isApproximate: true
},
releaseInformation: [{
territories: [{ code: 'US' }],
salesStartDate: '2024-03-15T00:00:00-05:00'
}]
}]
};
Working with Durations
// Parse duration string
function parseDuration(isoDuration: string): number {
// Convert "PT3M45S" to total seconds
const match = isoDuration.match(/PT(?:(\d+)H)?(?:(\d+)M)?(?:(\d+)S)?/);
if (!match) return 0;
const hours = parseInt(match[1] || '0', 10);
const minutes = parseInt(match[2] || '0', 10);
const seconds = parseInt(match[3] || '0', 10);
return hours * 3600 + minutes * 60 + seconds;
}
// Format duration from seconds
function formatDuration(totalSeconds: number): string {
const hours = Math.floor(totalSeconds / 3600);
const minutes = Math.floor((totalSeconds % 3600) / 60);
const seconds = totalSeconds % 60;
let duration = 'PT';
if (hours > 0) duration += `${hours}H`;
if (minutes > 0) duration += `${minutes}M`;
if (seconds > 0) duration += `${seconds}S`;
return duration;
}
// Usage
const track = result.flat.resources.soundRecordings[0];
const durationSeconds = parseDuration(track.duration?.value || 'PT0S');
console.log(`Track length: ${Math.floor(durationSeconds / 60)}:${(durationSeconds % 60).toString().padStart(2, '0')}`);
Period Calculations
function isPeriodActive(period: Period, date: Date = new Date()): boolean {
const now = date.toISOString();
// Check start date
if (period.startDate && now < period.startDate) {
return false;
}
// Check end date
if (period.endDate && !period.isOpenEnded && now > period.endDate) {
return false;
}
return true;
}
// Usage with deals
const activeDeal = result.flat.deals.find(deal =>
!deal.validityPeriod || isPeriodActive(deal.validityPeriod)
);
Timezone Handling
UTC vs Local Time
// Prefer UTC for international distribution
const utcDate = "2024-03-15T00:00:00Z";
// Local time with offset
const localDate = "2024-03-15T00:00:00-05:00"; // EST
// Date only (timezone-agnostic)
const dateOnly = "2024-03-15";
Territory-Specific Dates
Different territories may have different release dates:
const releaseInfo = [{
territories: [{ code: 'US' }],
salesStartDate: '2024-03-15T00:00:00-05:00' // EST
}, {
territories: [{ code: 'JP' }],
salesStartDate: '2024-03-16T00:00:00+09:00' // JST (next day)
}];
See Also
- Deal Models - Period usage in licensing
- Territory Models - Territory-specific dates
- Release Models - Release date handling