
org.eclipse.jetty.logging.Timestamp Maven / Gradle / Ivy
//
// ========================================================================
// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others.
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
// which is available at https://www.apache.org/licenses/LICENSE-2.0.
//
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
// ========================================================================
//
package org.eclipse.jetty.logging;
import java.time.Instant;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.TimeZone;
/**
*
* This is a super stripped down version of {@code DateCache} from jetty-util.
*
*
*
* This is a private class, only 1 method is exposed. {@link #formatNow(long, StringBuilder)},
* Caching of the formatted timestamp up to the current second is still performed.
* Format updates the StringBuilder directly.
* And millisecond formatting is done by this class.
*
*/
class Timestamp
{
private final DateTimeFormatter tzFormatter;
private final ZoneId zoneId;
private volatile Tick tick;
public static class Tick
{
private final long seconds;
private final String formattedString;
public Tick(long seconds, String string)
{
this.seconds = seconds;
formattedString = string;
}
}
public Timestamp(TimeZone timeZone)
{
zoneId = timeZone.toZoneId();
tzFormatter = DateTimeFormatter
.ofPattern("yyyy-MM-dd HH:mm:ss")
.withZone(zoneId);
tick = null;
}
/**
* Format a timestamp according to our stored formatter.
* The passed time is expected to be close to the current time, so it is
* compared to the last value passed and if it is within the same second,
* the format is reused. Otherwise a new cached format is created.
*
* @param now the milliseconds since unix epoch
*/
public void formatNow(long now, StringBuilder builder)
{
long seconds = now / 1000;
int ms = (int)(now % 1000);
Tick tick = this.tick;
// Is this the cached time
if (tick != null && tick.seconds == seconds)
{
builder.append(tick.formattedString);
}
else
{
formatTick(now, builder);
}
if (ms > 99)
{
builder.append('.');
}
else if (ms > 9)
{
builder.append(".0");
}
else
{
builder.append(".00");
}
builder.append(ms);
}
protected void formatTick(long now, StringBuilder builder)
{
long seconds = now / 1000;
Tick tick = this.tick;
// recheck the tick, to save multiple formats
if (tick == null || tick.seconds != seconds)
{
String s = ZonedDateTime.ofInstant(Instant.ofEpochMilli(now), zoneId).format(tzFormatter);
builder.append(s);
this.tick = new Tick(seconds, s);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy