Date functions for Bicep

This article describes the Bicep functions for working with dates.

dateTimeAdd

dateTimeAdd(base, duration, [format])

Adds a time duration to a base value. ISO 8601 format is expected.

Namespace: sys.

Parameters

Parameter Required Type Description
base Yes string The starting datetime value for the addition. Use ISO 8601 timestamp format.
duration Yes string The time value to add to the base. It can be a negative value. Use ISO 8601 duration format.
format No string The output format for the date time result. If not provided, the format of the base value is used. Use either standard format strings or custom format strings.

Return value

The datetime value that results from adding the duration value to the base value.

Remarks

The dateTimeAdd function doesn't take leap years into consideration, and P1Y should be interpreted as P365D, while P1M should be interpreted as P30D. The following Bicep file shows some examples:

output addOneYearNonLeap string = dateTimeAdd('2023-01-01 00:00:00Z', 'P1Y') //2024-01-01T00:00:00Z
output addOneYearLeap string = dateTimeAdd('2024-01-01 00:00:00Z', 'P1Y')  //2024-12-31T00:00:00Z

output addOneMonthNonLeap string = dateTimeAdd('2023-02-01 00:00:00Z', 'P1M') //2023-03-03T00:00:00Z
output addOneMonthLeap string = dateTimeAdd('2024-02-01 00:00:00Z', 'P1M') //2023-03-02T00:00:00Z

In the preceding example, considering 2023 as a non-leap year, the outcome of adding one year to the initial day of the year is 2024-01-01T00:00:00Z. Conversely, adding one year to the starting day of 2024, a leap year, results in 2024-12-31T00:00:00Z, not 2025-01-01T00:00:00Z, given that a leap year comprises 366 days instead of 365 days. Furthermore, the distinction between leap and non-leap years becomes apparent when adding one month to the first day of February, leading to varying day-of-the-month results.

Examples

The following example shows different ways of adding time values.

param baseTime string = utcNow('u')

var add3Years = dateTimeAdd(baseTime, 'P3Y')
var subtract9Days = dateTimeAdd(baseTime, '-P9D')
var add1Hour = dateTimeAdd(baseTime, 'PT1H')

output add3YearsOutput string = add3Years
output subtract9DaysOutput string = subtract9Days
output add1HourOutput string = add1Hour

When the preceding example is deployed with a base time of 2020-04-07 14:53:14Z, the output is:

Name Type Value
add3YearsOutput String 4/7/2023 2:53:14 PM
subtract9DaysOutput String 3/29/2020 2:53:14 PM
add1HourOutput String 4/7/2020 3:53:14 PM

The next example shows how to set the start time for an Automation schedule.

param omsAutomationAccountName string = 'demoAutomation'
param scheduleName string = 'demSchedule1'
param baseTime string = utcNow('u')

var startTime = dateTimeAdd(baseTime, 'PT1H')

...

resource scheduler 'Microsoft.Automation/automationAccounts/schedules@2022-08-08' = {
  name: concat(omsAutomationAccountName, '/', scheduleName)
  properties: {
    description: 'Demo Scheduler'
    startTime: startTime
    interval: 1
    frequency: 'Hour'
  }
}

dateTimeFromEpoch

dateTimeFromEpoch(epochTime)

Converts an epoch time integer value to an ISO 8601 datetime.

Namespace: sys.

Parameters

Parameter Required Type Description
epochTime Yes int The epoch time to convert to a datetime string.

Return value

An ISO 8601 datetime string.

Remarks

This function requires Bicep CLI version 0.5.X or higher.

Example

The following example shows output values for the epoch time functions.

param convertedEpoch int = dateTimeToEpoch(dateTimeAdd(utcNow(), 'P1Y'))

var convertedDatetime = dateTimeFromEpoch(convertedEpoch)

output epochValue int = convertedEpoch
output datetimeValue string = convertedDatetime

The output is:

Name Type Value
datetimeValue String 2023-05-02T15:16:13Z
epochValue Int 1683040573

dateTimeToEpoch

dateTimeToEpoch(dateTime)

Converts an ISO 8601 datetime string to an epoch time integer value.

Namespace: sys.

Parameters

Parameter Required Type Description
dateTime Yes string The datetime string to convert to an epoch time.

Return value

An integer that represents the number of seconds from midnight on January 1, 1970.

Remarks

This function requires Bicep CLI version 0.5.X or higher.

Examples

The following example shows output values for the epoch time functions.

param convertedEpoch int = dateTimeToEpoch(dateTimeAdd(utcNow(), 'P1Y'))

var convertedDatetime = dateTimeFromEpoch(convertedEpoch)

output epochValue int = convertedEpoch
output datetimeValue string = convertedDatetime

The output is:

Name Type Value
datetimeValue String 2023-05-02T15:16:13Z
epochValue Int 1683040573

The next example uses the epoch time value to set the expiration for a key in a key vault.

@description('The location into which the resources should be deployed.')
param location string = resourceGroup().location

@description('The Tenant Id that should be used throughout the deployment.')
param tenantId string = subscription().tenantId

@description('The name of the existing User Assigned Identity.')
param userAssignedIdentityName string

@description('The name of the resource group for the User Assigned Identity.')
param userAssignedIdentityResourceGroupName string

@description('The name of the Key Vault.')
param keyVaultName string  = 'vault-${uniqueString(resourceGroup().id)}'

@description('Name of the key in the Key Vault')
param keyVaultKeyName string = 'cmkey'

@description('Expiration time of the key')
param keyExpiration int = dateTimeToEpoch(dateTimeAdd(utcNow(), 'P1Y'))

@description('The name of the Storage Account')
param storageAccountName string =  'storage${uniqueString(resourceGroup().id)}'


resource userAssignedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' existing = {
  scope: resourceGroup(userAssignedIdentityResourceGroupName)
  name: userAssignedIdentityName  
}

resource keyVault 'Microsoft.KeyVault/vaults@2021-10-01' = {
  name: keyVaultName
  location: location
  properties: {
    sku: {
      name: 'standard'
      family: 'A'
    }
    enableSoftDelete: true
    enablePurgeProtection: true
    enabledForDiskEncryption: true
    tenantId: tenantId
    accessPolicies: [
      {
        tenantId: tenantId
        permissions: {
          keys: [
            'unwrapKey'
            'wrapKey'
            'get'
          ]
        }
        objectId: userAssignedIdentity.properties.principalId
      }
    ]
  }
}

resource kvKey 'Microsoft.KeyVault/vaults/keys@2021-10-01' = {
  parent: keyVault
  name: keyVaultKeyName
  properties: {
    attributes: {
      enabled: true
      exp: keyExpiration
    }
    keySize: 4096
    kty: 'RSA'
  }
}

resource storage 'Microsoft.Storage/storageAccounts@2021-04-01' = {
  name: storageAccountName
  location: location
  sku: {
    name: 'Standard_LRS'
  }
  kind: 'StorageV2'
  identity: {
    type: 'UserAssigned'
    userAssignedIdentities: {
      '${userAssignedIdentity.id}': {}
    }
  }
  properties: {
    accessTier: 'Hot'
    supportsHttpsTrafficOnly: true
    minimumTlsVersion: 'TLS1_2'
    encryption: {
      identity: {
        userAssignedIdentity: userAssignedIdentity.id
      }
      services: {
         blob: {
           enabled: true
         }
      }
      keySource: 'Microsoft.Keyvault'
      keyvaultproperties: {
        keyname: kvKey.name
        keyvaulturi: endsWith(keyVault.properties.vaultUri,'/') ? substring(keyVault.properties.vaultUri,0,length(keyVault.properties.vaultUri)-1) : keyVault.properties.vaultUri
      }
    }
  }
}

utcNow

utcNow(format)

Returns the current (UTC) datetime value in the specified format. If no format is provided, the ISO 8601 (yyyyMMddTHHmmssZ) format is used. This function can only be used in the default value for a parameter.

Namespace: sys.

Parameters

Parameter Required Type Description
format No string The URI encoded value to convert to a string. Use either standard format strings or custom format strings.

Remarks

You can only use this function within an expression for the default value of a parameter. Using this function anywhere else in a Bicep file returns an error. The function isn't allowed in other parts of the Bicep file because it returns a different value each time it's called. Deploying the same Bicep file with the same parameters wouldn't reliably produce the same results.

If you use the option to rollback on error to an earlier successful deployment, and the earlier deployment includes a parameter that uses utcNow, the parameter isn't reevaluated. Instead, the parameter value from the earlier deployment is automatically reused in the rollback deployment.

Be careful redeploying a Bicep file that relies on the utcNow function for a default value. When you redeploy and don't provide a value for the parameter, the function is reevaluated. If you want to update an existing resource rather than create a new one, pass in the parameter value from the earlier deployment.

Return value

The current UTC datetime value.

Examples

The following example shows different formats for the datetime value.

param utcValue string = utcNow()
param utcShortValue string = utcNow('d')
param utcCustomValue string = utcNow('M d')

output utcOutput string = utcValue
output utcShortOutput string = utcShortValue
output utcCustomOutput string = utcCustomValue

The output from the preceding example varies for each deployment but will be similar to:

Name Type Value
utcOutput string 20190305T175318Z
utcShortOutput string 03/05/2019
utcCustomOutput string 3 5

The next example shows how to use a value from the function when setting a tag value.

param utcShort string = utcNow('d')
param rgName string

resource myRg 'Microsoft.Resources/resourceGroups@2022-09-01' = {
  name: rgName
  location: 'westeurope'
  tags: {
    createdDate: utcShort
  }
}

output utcShortOutput string = utcShort

Next steps