Unix Hex Timestamp Converter
Convert Unix timestamps in hex (0x…) or decimal — auto-detects seconds vs milliseconds with a manual override. Fully client-side.
Related Tools
UNIX Timestamp Converter · LDAP / FILETIME Converter · Apple Cocoa / Core Foundation Time · Time Since / Until
1) Hex / Decimal Unix Timestamp → Date
0x
is accepted. Negative values supported.
2) Date → Unix Timestamp (Hex & Decimal)
About Unix Hex Timestamps
A Unix timestamp is the number of seconds (or milliseconds) since
1970-01-01T00:00:00Z. Many tools and logs render this number in hexadecimal.
This converter accepts hex (with or without 0x
) or decimal, detects whether the value is in
seconds or milliseconds, and shows both formats.
- Auto-detect: Large magnitudes (≈ ≥ 1e11, i.e., ms) are treated as milliseconds; smaller as seconds. You can override.
- Signed / negative: Values before 1970 (negative) are supported.
- Precision: Internals use
BigInt
to avoid rounding. Display is to millisecond precision.
Unix Hex Timestamp: Code Snippets & How-To
A Unix timestamp represents seconds (or milliseconds) since 1970-01-01T00:00:00Z.
Many logs use hexadecimal (with or without a 0x
prefix). These examples show how to parse
hex/decimal, auto-detect seconds vs milliseconds, and convert to human-readable dates.
Rule of thumb
- If the absolute value is ≳
1e11
, it’s likely milliseconds; otherwise seconds. - Negative values (before 1970) are valid; floor division is required when deriving seconds from ms.
JavaScript (Browser/Node)
function parseBigIntFlexible(s) {
s = s.trim();
if (/^-?0x[0-9a-f]+$/i.test(s)) return BigInt(s);
if (/^-?[0-9a-f]+$/i.test(s) && /[a-f]/i.test(s)) return BigInt('0x'+s.replace(/^-/,''));
if (/^-?\d+$/.test(s)) return BigInt(s);
throw new Error('Invalid hex/decimal integer');
}
function unitAuto(bi) {
const abs = bi < 0n ? -bi : bi;
return abs >= 100_000_000_000n ? 'ms' : 's';
}
function floorDiv(a, b) { // floor for negatives
const q = a / b, r = a % b;
return (r === 0n || (a >= 0n) === (b >= 0n)) ? q : q - 1n;
}
// Hex/dec → Date
function hexUnixToDate(s, unit = 'auto') {
let bi = parseBigIntFlexible(s);
if (unit === 'auto') unit = unitAuto(bi);
const ms = unit === 's' ? bi * 1000n : bi;
const max = 8_640_000_000_000_000n;
const clamped = ms > max ? max : (ms < -max ? -max : ms);
return new Date(Number(clamped));
}
// Date → hex/dec (seconds & milliseconds)
function dateToUnixHex(date = new Date()) {
const ms = BigInt(date.getTime());
const sec = floorDiv(ms, 1000n);
return {
seconds_dec: sec.toString(),
seconds_hex: '0x'+sec.toString(16).toUpperCase(),
millis_dec: ms.toString(),
millis_hex: '0x'+ms.toString(16).toUpperCase()
};
}
Python 3
import datetime, math, re
HEX_RE = re.compile(r'^-?(0x)?[0-9a-f]+$', re.IGNORECASE)
def parse_int_flexible(s: str) -> int:
s = s.strip()
if not s:
raise ValueError("empty input")
if s.lower().startswith('-0x'):
return -int(s[3:], 16)
if s.lower().startswith('0x'):
return int(s, 16)
if HEX_RE.match(s) and any(c.isalpha() for c in s):
return int(s, 16) if not s.startswith('-') else -int(s[1:], 16)
return int(s, 10)
def unit_auto(v: int) -> str:
return 'ms' if abs(v) >= 100_000_000_000 else 's'
def hex_unix_to_datetime(s: str, unit: str = 'auto') -> datetime.datetime:
v = parse_int_flexible(s)
if unit == 'auto':
unit = unit_auto(v)
ms = v if unit == 'ms' else v * 1000
# timezone-aware UTC datetime
return datetime.datetime.fromtimestamp(ms / 1000, tz=datetime.timezone.utc)
def datetime_to_unix(dt: datetime.datetime = None):
if dt is None:
dt = datetime.datetime.now(datetime.timezone.utc)
if dt.tzinfo is None:
dt = dt.astimezone() # local -> aware
ms = int(dt.timestamp() * 1000)
sec = math.floor(ms / 1000) # floor for negatives
return {
'seconds_dec': str(sec),
'seconds_hex': hex(sec),
'millis_dec': str(ms),
'millis_hex': hex(ms)
}
C (portable)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <inttypes.h>
static int is_hexlike(const char *s){
if (!s || !*s) return 0;
if (s[0]=='-' && s[1]) s++;
if (s[0]=='0' && (s[1]=='x' || s[1]=='X')) return 1;
for (const char *p=s; *p; ++p) if ((*p>='a' && *p<='f') || (*p>='A' && *p<='F')) return 1;
return 0;
}
int main(int argc, char **argv){
if (argc < 2){ fprintf(stderr, "usage: %s <hex|dec> [s|ms]\n", argv[0]); return 1; }
const char *in = argv[1];
const char *unit = (argc >= 3) ? argv[2] : "auto";
int isneg = (in[0]=='-');
if (isneg && in[1]=='0' && (in[2]=='x' || in[2]=='X')) in += 3;
char *end = NULL;
int base = is_hexlike(in) ? 16 : 10;
long long sign = isneg ? -1 : 1;
unsigned long long mag = strtoull(isneg ? in+1 : in, &end, base);
long long val = (long long)(sign * (long long)mag);
const char *mode = unit;
if (strcmp(mode,"auto")==0){
mode = ( llabs(val) >= 100000000000LL ) ? "ms" : "s";
}
long long ms = (strcmp(mode,"s")==0) ? val * 1000LL : val;
time_t secs = (time_t)(ms/1000LL - ((ms<0 && ms%1000LL)!=0)); // floor for negatives
struct tm tm_utc;
gmtime_r(&secs, &tm_utc);
char buf[64];
strftime(buf, sizeof(buf), "%Y-%m-%dT%H:%M:%SZ", &tm_utc);
printf("UTC ISO8601: %s\n", buf);
printf("UNIX seconds dec: %lld\n", (long long)secs);
printf("UNIX seconds hex: 0x%llX\n", (unsigned long long)secs);
printf("UNIX millis dec: %lld\n", ms);
printf("UNIX millis hex: 0x%llX\n", (unsigned long long)ms);
return 0;
}
C# (.NET)
using System;
using System.Globalization;
static class UnixHex {
static bool IsHexLike(string s) => s.StartsWith("0x", true, CultureInfo.InvariantCulture) || s.IndexOfAny("abcdefABCDEF".ToCharArray()) >= 0;
public static DateTimeOffset ParseToUtc(string s, string unit = "auto"){
s = s.Trim();
bool neg = s.StartsWith("-");
string core = s.StartsWith("-0x", true, CultureInfo.InvariantCulture) ? s.Substring(3)
: s.StartsWith("0x", true, CultureInfo.InvariantCulture) ? s.Substring(2)
: s;
long val = Convert.ToInt64((IsHexLike(s)) ? (neg ? "-" + Convert.ToInt64(core,16).ToString() : Convert.ToInt64(core,16).ToString())
: s, 10);
string mode = unit;
if (mode=="auto") mode = (Math.Abs(val) >= 100_000_000_000L) ? "ms" : "s";
long ms = (mode=="s") ? val*1000L : val;
return DateTimeOffset.FromUnixTimeMilliseconds(ms);
}
}
Go
package main
import (
"fmt"
"strconv"
"strings"
"time"
)
func parseIntFlexible(s string) (int64, error) {
s = strings.TrimSpace(s)
neg := strings.HasPrefix(s, "-")
core := s
if strings.HasPrefix(strings.ToLower(s), "-0x") { core = s[3:]; neg = true }
if strings.HasPrefix(strings.ToLower(s), "0x") { core = s[2:] }
base := 10
if strings.ContainsAny(core, "abcdefABCDEF") { base = 16 }
u, err := strconv.ParseUint(strings.TrimPrefix(core, "-"), base, 64)
if err != nil { return 0, err }
if neg { return -int64(u), nil }
return int64(u), nil
}
func unitAuto(v int64) string {
if v < 0 { v = -v }
if v >= 100_000_000_000 { return "ms" }
return "s"
}
func main() {
v, _ := parseIntFlexible("0x6512BD00")
mode := unitAuto(v)
if mode == "s" { v = v * 1000 }
t := time.UnixMilli(v)
fmt.Println(t.UTC().Format(time.RFC3339Nano))
}
Java / Kotlin
// Java
import java.time.*;
import java.util.*;
public class UnixHex {
static boolean isHexLike(String s){
return s.startsWith("0x") || s.matches(".*[A-Fa-f].*");
}
static long parseFlexible(String s){
s = s.trim();
boolean neg = s.startsWith("-");
String core = s.startsWith("-0x") ? s.substring(3) : (s.startsWith("0x") ? s.substring(2) : s);
long v = isHexLike(s) ? Long.parseUnsignedLong(core,16) : Long.parseLong(core,10);
return neg ? -v : v;
}
static String unitAuto(long v){ return Math.abs(v) >= 100_000_000_000L ? "ms" : "s"; }
public static void main(String[] args){
long v = parseFlexible("5F5E100");
String mode = unitAuto(v);
long ms = mode.equals("s") ? v*1000L : v;
Instant inst = Instant.ofEpochMilli(ms);
System.out.println(inst.toString()); // ISO-8601 UTC
}
}
Rust
use chrono::{DateTime, Utc, TimeZone};
fn parse_flexible(s: &str) -> i128 {
let s = s.trim();
let neg = s.starts_with('-');
let core = s.strip_prefix("-0x").or_else(|| s.strip_prefix("0x")).unwrap_or(s);
let mut v: i128 = if s.contains(|c: char| c.is_ascii_hexdigit() && c.is_ascii_alphabetic()) {
i128::from_str_radix(core, 16).unwrap()
} else { core.parse().unwrap() };
if neg { v = -v }
v
}
fn unit_auto(v: i128) -> 'static str { if v.abs() >= 100_000_000_000 { "ms" } else { "s" } }
fn main(){
let v = parse_flexible("0x0000018EDDDEAD");
let unit = unit_auto(v);
let ms: i128 = if unit == "s" { v * 1000 } else { v };
let secs = (ms.div_euclid(1000)) as i64; // floor
let nsec = ((ms.rem_euclid(1000)) * 1_000_000) as u32;
let dt: DateTime<Utc> = Utc.timestamp_opt(secs, nsec).unwrap();
println!("{}", dt.to_rfc3339_opts(chrono::SecondsFormat::Millis, true));
}
PHP
<?php
function parse_int_flexible(string $s): int {
$s = trim($s);
if (stripos($s, '-0x') === 0) return -intval(substr($s,3), 16);
if (stripos($s, '0x') === 0) return intval(substr($s,2), 16);
if (preg_match('/[a-f]/i', $s)) return intval($s, 16);
return intval($s, 10);
}
function unit_auto(int $v): string {
return (abs($v) >= 100_000_000_000) ? 'ms' : 's';
}
$v = parse_int_flexible('0x6512BD00');
$mode = unit_auto($v);
$ms = ($mode === 's') ? $v * 1000 : $v;
$dt = (new DateTimeImmutable('@' . intdiv($ms,1000)))->setTimezone(new DateTimeZone('UTC'));
echo $dt->format('c'); // ISO-8601 UTC
Ruby
def parse_int_flexible(s)
s = s.strip
return -s[3..].to_i(16) if s.downcase.start_with?('-0x')
return s[2..].to_i(16) if s.downcase.start_with?('0x')
return s.to_i(16) if s =~ /[a-f]/i
s.to_i
end
def unit_auto(v) = v.abs >= 100_000_000_000 ? 'ms' : 's'
v = parse_int_flexible('5F5E100')
mode = unit_auto(v)
ms = mode == 's' ? v * 1000 : v
t = Time.at(ms / 1000.0).utc
puts t.iso8601(3)
Bash (GNU coreutils)
# Hex/dec -> ISO UTC (seconds assumed; set UNIT=ms for millis)
IN="${1:-0x6512BD00}"
UNIT="${2:-auto}"
# normalize to decimal
if [[ "$IN" =~ ^-?0x[0-9a-fA-F]+$ ]]; then
DEC=$((IN)) # bash can parse 0x...
elif [[ "$IN" =~ [a-fA-F] ]]; then
DEC=$((16#$IN))
else
DEC=$IN
fi
if [[ "$UNIT" == "auto" ]]; then
ABS=${DEC#-}
[[ ${#ABS} -ge 11 ]] && UNIT=ms || UNIT=s
fi
if [[ "$UNIT" == "ms" ]]; then
SEC=$(( DEC / 1000 ))
else
SEC=$DEC
fi
date -u -d "@$SEC" +"%Y-%m-%dT%H:%M:%S%z"