Get Certificate Expiry Date in Unix Time Format

Abstract: Convert an SSL certificate's expiration date to a Unix timestamp for scripting and monitoring on Linux, macOS, or BSD.

Created: 2026-10-02 by
You can extract a certificate's expiry date in Unix time format by piping the output of openssl x509 into date -d. This method converts the human-readable expiration string directly into a numeric timestamp, which is essential for scripting, automated monitoring, and integration with systems that require epoch seconds rather than formatted dates.

Understanding the OpenSSL Output Format

Before converting the date, it is helpful to understand how OpenSSL presents certificate information. The command openssl x509 -enddate -noout retrieves the "notAfter" field from a certificate file or standard input. By default, this output appears as a readable string, such as notAfter=Dec 31 23:59:59 2025 GMT. While this format is easy for humans to read, it is not immediately usable in most programming languages or shell scripts that expect a numeric value representing the number of seconds since the Unix epoch (January 1, 1970). To get this raw data, you typically point OpenSSL at your certificate file using the -in flag. For example, running openssl x509 -in cert.pem -enddate -noout will print the expiration line. The -noout flag ensures that only the specific requested field is displayed, preventing other certificate details from cluttering the output stream. This clean output is critical for the next step, where we parse the string.

Converting to Unix Time on Linux

On Linux systems, the GNU version of the date command provides robust parsing capabilities. You can combine OpenSSL with date using process substitution or pipes to achieve the conversion in a single line. The most reliable approach involves extracting the date string and feeding it into date -d, which interprets natural language date formats. Here is the standard one-liner for Bash:
openssl x509 -in cert.pem -enddate -noout | sed 's/notAfter=//' | xargs -I {} date -d "{}" +%s
Let us break down why each component is necessary. First, sed 's/notAfter=//' strips the prefix from the OpenSSL output, leaving only the date portion. Without this, date -d might fail because it does not recognize the notAfter= label. Next, xargs -I {} passes the cleaned string as an argument to the date command. Finally, +%s tells date to output the result in seconds since the epoch. If you prefer a more concise approach without stripping the prefix manually, some versions of date can handle the full string if you use the --date option correctly, but explicit cleaning via sed or awk is safer across different environments. For instance, using awk allows you to isolate the second field if the separator changes:
openssl x509 -in cert.pem -enddate -noout | awk -F= '{print $2}' | xargs -I {} date -d "{}" +%s
This method ensures that regardless of whether the certificate uses UTC or local time notation, the conversion remains accurate. The resulting number can be stored in a variable for comparison against current time using $(date +%s).

Handling macOS and BSD Systems

A common pitfall occurs when running these commands on macOS or FreeBSD. These systems use BSD-derived utilities, where the date command lacks the -d flag for parsing arbitrary strings. Instead, you must use the -j (jump) and -f (format) flags to specify both the input format and the desired output. The OpenSSL output format on these systems is identical to Linux, so the initial extraction steps remain the same. However, the final conversion requires a different syntax. You need to tell date exactly what format the incoming string uses. The standard format for OpenSSL output is %b %d %T %Y %Z, which corresponds to Month Day Time Year Timezone. Here is the compatible command for macOS/BSD:
openssl x509 -in cert.pem -enddate -noout | sed 's/notAfter=//' | xargs -I {} date -j -f "%b %d %T %Y %Z" "{}" +%s
The -j flag prevents date from setting the system clock, while -f defines the parser. If you omit the -f flag, date will attempt to guess the format, which often leads to errors or incorrect results. This distinction is vital for cross-platform scripts that manage certificates on both Linux servers and macOS development machines.

Using Python for Cross-Platform Reliability

For complex automation tasks, relying on shell utilities can introduce fragility due to differences in OS-specific tools. Python offers a robust alternative that works consistently across Windows, Linux, and macOS. Using the built-in ssl and datetime modules, you can parse the certificate and calculate the Unix timestamp without invoking external processes. First, load the certificate using ssl.PEM_cert_to_DER_cert or the cryptography library. If using the standard library, you can convert the PEM to DER bytes and then use ssl.DER_cert_to_PEM_cert logic, but it is often easier to use the cryptography package which is widely available. Once loaded, access the not_valid_after_utc property.
from cryptography import x509
from cryptography.hazmat.backends import default_backend
import datetime

with open("cert.pem", "rb") as f:
    cert = x509.load_pem_x509_certificate(f.read(), default_backend())

expiry_date = cert.not_valid_after_utc
unix_time = int(expiry_date.timestamp())
print(unix_time)
This approach eliminates the need for sed or platform-specific date flags. It also handles timezone conversions automatically, ensuring that the Unix timestamp is always correct relative to UTC. This is particularly useful if you are building a web service or a CI/CD pipeline where consistent behavior across different deployment environments is required.

Integrating with Monitoring Scripts

Once you have the Unix timestamp, you can easily check if a certificate is expiring soon. Compare the extracted expiry time against the current time plus a buffer period. For example, to alert if a certificate expires within 30 days, calculate the threshold as current_time + (30 * 86400). This technique is frequently used in conjunction with other certificate management tasks. For instance, if you are managing serial numbers explicitly, you might want to ensure that the new certificate has a valid expiry before deploying it. Similarly, when dealing with P12 authentication, verifying the chain validity includes checking the expiry of intermediate certificates. Related articles that may assist with broader certificate management include How to Set Length of Certificate Serial Number Explicitly? for handling metadata, and P12 Certificate Authentication for securing private key bundles. Additionally, if you are updating your environment, see How to Update OpenSSL to 3.1.1 from 1.0.2n in Node.js to ensure your tools support modern certificate formats.

Frequently Asked Questions

What happens if the certificate is self-signed?

The expiry date extraction process is identical for self-signed and CA-signed certificates. OpenSSL reads the "notAfter" field regardless of the trust chain. Ensure you are pointing the -in flag at the correct .pem or .crt file containing the leaf certificate.

Can I get the expiry date in milliseconds instead of seconds?

Standard Unix time is measured in seconds. To get milliseconds, simply multiply the output of +%s by 1000 in your shell script or multiply the Python integer by 1000. Most JavaScript environments and many APIs accept either format, but verify the API documentation for precision requirements.

Why does my date command return an error on macOS?

This usually happens because macOS uses BSD date, which does not support the -d flag. Use date -j -f "%b %d %T %Y %Z" instead to explicitly define the input format. Always test your scripts on both Linux and macOS if they are intended for cross-platform use.

How do I handle certificates with future expiry dates in scripts?

If a certificate is not yet valid, the notBefore field will be in the future. When comparing against $(date +%s), the expiry timestamp will be greater than the current time. Ensure your logic checks if expiry > current + buffer to avoid false positive alerts for certificates that are already expired or not yet active.

Is there a way to check multiple certificates at once?

You can loop through a directory of certificates using a for loop in Bash. Iterate over all *.pem files, apply the conversion command, and store the results in an associative array or temporary file. This allows you to batch-check expiration times for bulk certificate deployments.

Latest News

How to Display Output of xterm Command in Terminal Screen using Cron

Resolve the inability to display xterm output in a terminal screen from cron by redirecting logs or using wall instead of insecure X11 workarounds.

Read More
Expose Local Server on VPS Preserving Real Client IPs (OS Level)

Resolve VPS logging showing only gateway IPs by configuring reverse proxies to forward real client addresses via X-Forwarded-For headers.

Read More
How to Clear Recent Files History in Linux without Deleting Actual Files?

Clear recent files history in Linux by deleting ~/.local/share/recently-used.xbel without removing the actual files.

Read More
Best HDD Copy Strategy: Manually Syncing and Rewriting Scratch

Resolve data drift between two 4TB hard drives by using rsync with the --delete flag to manually sync and rewrite scratch data for an exact mirror.

Read More
Understanding Bash Prompt Abbreviations: An Overview

Resolve repetitive typing errors by creating and persisting Bash aliases in the .bashrc file for improved command-line efficiency.

Read More
Free Tools and Methods to Log Real-Time Performance Details in Task Manager

Log real-time CPU and memory metrics to CSV files using Windows Performance Monitor Data Collector Sets to troubleshoot system slowness.

Read More
Contact Qatar Airways Customer Service: Phone Number, Help Center, and More

Resolve urgent Qatar Airways reservation issues like flight changes and baggage claims using the US phone number +1801-855-5905 or online self-service tools.

Read More
Windows 11: Alt Codes Displaying Wrong Characters - Solutions

Resolve Windows 11 Alt codes showing wrong characters by verifying the US keyboard layout and enabling Num Lock.

Read More
Run Programs with Elevated Privileges: A Comprehensive Guide

Eliminates the need to type sudo for frequent administrative tasks by configuring .bashrc aliases or functions.

Read More
Dynamically Changing Dates in Excel Formulas Using Cells

Eliminate manual date updates in Excel by using cell references to create dynamic formulas that automatically adjust calculations when input dates change.

Read More
Granting Edit Access to a Specific Excel Sheet in an Office 365 User Email ID-Based Login

Excel Online lacks native sheet-level permissions, so users must split workbooks or use worksheet protection to isolate edit access for specific tabs.

Read More
Creating Network Load on Local Wi-Fi from One PC

Generate sustained Wi-Fi bandwidth load from a single PC using a VM SFTP server to test router stability and throughput.

Read More
Changing the Default Editor for Batch Files in Windows 11's File Explorer

Resolve the issue of batch files opening in Notepad by changing the default editor to a preferred application like VS Code.

Read More
Gain WiFi Connection Minutes Before Losing it by Changing MAC Address

Bypass MAC address filtering to restore WiFi connectivity temporarily when a device is blocked by network administrators.

Read More
Photos Folders Turned Black: Troubleshooting Picture Applications on Windows

Resolve black screens in Windows Photos by resetting the app, updating graphics drivers, and repairing system files.

Read More
Troubleshooting High CPU Temperature Values: A Step-by-Step Guide

Resolve high CPU temperatures and thermal throttling by monitoring with Speedfan, cleaning dust from cooling components, and replacing degraded thermal paste.

Read More
Make cURL establish TLS connection with CA unknown

Resolve cURL TLS connection failures with unknown or self-signed certificates by using the --insecure flag to bypass CA validation.

Read More
Troubleshooting Incorrect Network Metrics Values in Grafana, Prometheus, InfluxDB, and Telegraf

Fix incorrect network metrics in Grafana, Prometheus, InfluxDB, and Telegraf by verifying interface selection, resolving unit mismatches, and handling counter resets.

Read More
Start Another Terminal Window (cmd.exe) Windows Repair/Troubleshoot

Provides step-by-step instructions to access the Windows Command Prompt via bootable media for advanced system repair and troubleshooting.

Read More
Thinkpad P1 Gen 6: Sudden Thunderbolt 3 Dock USB-C Charging Stopped Working

Resolve sudden Thunderbolt 3 dock USB-C charging and internet failure on ThinkPad P1 Gen 6 by updating firmware, resetting the dock, and adjusting power settings.

Read More
ASUS Windows 11 Laptop: Internet Connection Issue with Hotspot

Resolve ASUS Windows 11 laptop spinning wheel issue when connecting to mobile hotspot by resetting network stack, disabling IPv6, and adjusting power settings.

Read More
Developing iOS Project with Firebase: Logging in and Sending Push Notifications

Integrates Firebase to enable secure user authentication and push notifications in iOS applications.

Read More
Troubleshooting Bash Script with Suspected Issues of Spaces, Dashes, Filenames and Quoting

Resolve Bash script failures caused by word splitting, globbing, and special characters in filenames by applying proper quoting techniques.

Read More
Populating OneDrive Folder for Local Backup without Affecting Remote Files

Prevent OneDrive from deleting remote files during Windows reinstallation by unlinking the account or using symbolic links to isolate local data.

Read More
Force First Frame as Keyframe Without Re-encoding: A Quick Solution

Resolve inaccurate seeking and playback glitches by re-encoding video to ensure the first frame is a valid keyframe.

Read More
Find Information in Database Using WSL (Ubuntu) on Windows-10

Resolve database connection issues from WSL Ubuntu on Windows 10 by configuring client tools and network access to query remote or local servers.

Read More
Configuring a New Router with Different Networks: One Family, One Guest

Resolve IP conflicts and isolate guest traffic by configuring a second router with a distinct subnet via its WAN port.

Read More
Quickly Open Multiple Stock Websites with a Single Command

Solve the problem of manually opening multiple stock research websites by creating a single command to launch them simultaneously on Windows, macOS, or Linux.

Read More
Improved Adobe Acrobat Search Experience: Access Advanced Search with Ease

Access advanced search filters like case sensitivity and regex in Adobe Acrobat by clicking More Options in the Find bar.

Read More
Port Forwarding VM via OpenVPN: A Comprehensive Guide

Configure OpenVPN server and iptables to forward specific ports from VPN clients to a virtual machine's internal IP address.

Read More
Understanding Partitions in the 1980s: A Look Back at MS-DOS and Master Boot Record

Explains how the Master Boot Record and partition table enabled MS-DOS to manage multiple disk volumes on a single physical drive.

Read More
Windows 10 Enterprise: Keyboard Not Detected in Managed Organization with Admin Privileges

Resolve Windows 10 Enterprise keyboard detection failures caused by Group Policy restrictions, driver corruption, or USB enumeration errors.

Read More
Can't Find x86_64 Versions of Applications on MacOS arm64 (M1)

Resolve missing x86_64 app issues on M1 Macs by installing Rosetta 2 and reinstalling apps as universal binaries.

Read More
How to Hide Installation Source for an Android App

Manage Android app installation source visibility by using USB transfers or file managers to reduce browser traces and isolate data via work profiles.

Read More
Connecting Momentus 4200.2 ST9808210A Hard Drive via USB Cable

Resolve inability to access Seagate Momentus 4200.2 ST9808210A hard drive by connecting it via USB using a compatible SATA-to-USB adapter and configuring the disk in Windows.

Read More