time.c的Java实现

public class GMT {
public static final int EPOCH_YEAR = 1970;
public static final int[][] MONTH_DAYS = {
{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
{31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
};
public static final long MSECS_DAY = 1000*3600*24L; private long timestamp;
private int mil;
private int sec;
private int min;
private int hour;
private int wday;
private int mday;
private int yday;
private int mon;
private int year; public GMT(long timestamp, long shift) {
this.timestamp = timestamp + shift;
long dayclock = (this.timestamp % MSECS_DAY) / 1000L;
long dayno = this.timestamp / MSECS_DAY; mil = (int) (this.timestamp % 1000L);
sec = (int) (dayclock % 60);
min = (int) ((dayclock % 3600) / 60);
hour = (int) (dayclock / 3600);
wday = (int) ((dayno + 4) % 7);
while (dayno >= yearDays(EPOCH_YEAR + year)) {
dayno -= yearDays(EPOCH_YEAR + year);
year++;
}
year = EPOCH_YEAR + year;
yday = (int)dayno;
int[] monthDays = leapYear(year) ? MONTH_DAYS[1] : MONTH_DAYS[0];
while (dayno >= monthDays[mon]) {
dayno -= monthDays[mon];
mon++;
}
mon++;
mday = (int)dayno + 1;
} public long toLongInteger() {
return year * 10000000000000L
+ mon * 100000000000L
+ mday * 1000000000L
+ hour * 10000000L
+ min * 100000L
+ sec * 1000L
+ mil;
} private static int yearDays(int year) {
return leapYear(year) ? 366 : 365;
} private static boolean leapYear(int year) {
return ((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0);
} public int getMil() { return mil; }
public void setMil(int mil) { this.mil = mil; }
public int getSec() { return sec; }
public void setSec(int sec) { this.sec = sec; }
public int getMin() { return min; }
public void setMin(int min) { this.min = min; }
public int getHour() { return hour; }
public void setHour(int hour) { this.hour = hour; }
public int getWday() { return wday; }
public void setWday(int wday) { this.wday = wday; }
public int getMday() { return mday; }
public void setMday(int mday) { this.mday = mday; }
public int getYday() { return yday; }
public void setYday(int yday) { this.yday = yday; }
public int getMon() { return mon; }
public void setMon(int mon) { this.mon = mon; }
public int getYear() { return year; }
public void setYear(int year) { this.year = year; } public static void main(String[] args) {
long start = System.currentTimeMillis();
int total = 500000;
for (int i = 0; i < total; i ++) {
GMT gmt = new GMT(System.currentTimeMillis(), 1000L*3600*8);
System.out.println(gmt.toLongInteger());
}
long duration = System.currentTimeMillis() - start;
System.out.println("Total: " + duration + "ms, " + total/duration + "/ms");
}
}

可以作为Snowflake ID generator的前缀生成器, 好处是易于业务手工识别, 缺点是速度较慢, 与直接使用二进制的机制差一个数量级(sf默认实现是20k/ms, 这个只有2k/ms).

在带I/O的情况下, 能达到150/ms的生成速度, 比使用SimpleDateFormat的效率高很多, 还是可以使用的, 如果使用SimpleDateFormat的话, 只有30/ms的速度.

Update:

用这个改造出来的...TimeflakeId是类似于这样的

public class TimeflakeId {
private final static int SEQUENCE_MASK = 999;
private final RecyclableAtomicInteger atomic = new RecyclableAtomicInteger();
private long lastTimestamp = -1L;
private long lastTsFormatted = -1L; public long nextId() {
long timestamp = millisecond();
if (timestamp < lastTimestamp) {
throw new IllegalArgumentException(
String.format("Wait for %d milliseconds", lastTimestamp - timestamp));
} if (lastTimestamp == timestamp) {
int sequence = atomic.incrementAndRecycle(SEQUENCE_MASK);
if (sequence == 0) {
timestamp = waitTilNextMillis(lastTimestamp);
lastTimestamp = timestamp;
lastTsFormatted = getFormattedTimestamp();
}
return lastTsFormatted * 1000 + sequence;
} else {
atomic.set(0);
lastTimestamp = timestamp;
lastTsFormatted = getFormattedTimestamp();
return lastTsFormatted * 1000;
}
} private long waitTilNextMillis(final long lastTimestamp) {
long timestamp;
for (;;) {
timestamp = this.millisecond();
if (timestamp > lastTimestamp) {
return timestamp;
}
}
} private long millisecond() {
return System.currentTimeMillis();
} public static final int EPOCH_YEAR = 1970;
public static final long[][] MONTH_DAYS = {
{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
{31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
};
public static final long MSECS_DAY = 1000*3600*24L; private long getFormattedTimestamp() {
long ts = lastTimestamp + 1000L*3600*8;
long dayclock = (ts % MSECS_DAY) / 1000L;
long dayno = ts / MSECS_DAY; long mil = ts % 1000L;
long sec = dayclock % 60;
long min = (dayclock % 3600) / 60;
long hour = dayclock / 3600;
long year = 0;
while (dayno >= yearDays(EPOCH_YEAR + year)) {
dayno -= yearDays(EPOCH_YEAR + year);
year++;
}
long[] monthDays = leapYear(EPOCH_YEAR + year) ? MONTH_DAYS[1] : MONTH_DAYS[0];
int mon = 0;
while (dayno >= monthDays[mon]) {
dayno -= monthDays[mon];
mon++;
}
mon++;
long mday = dayno + 1; return ((year > 30)? year - 30 : year + 70) * 10000000000000L
+ mon * 100000000000L
+ mday * 1000000000L
+ hour * 10000000L
+ min * 100000L
+ sec * 1000L
+ mil;
} private static int yearDays(long year) {
return leapYear(year) ? 366 : 365;
} private static boolean leapYear(long year) {
return ((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0);
} public static void main(String[] args) {
TimeflakeId worker = new TimeflakeId();
long start = System.currentTimeMillis();
int total = 50000;
for (int i = 0; i < total; i ++) {
//System.out.println(worker.nextId());
worker.nextId();
}
long duration = System.currentTimeMillis() - start;
System.out.println("Total: " + duration + "ms, " + total/duration + "/ms");
}
}

RecyclableAtomicInteger 的实现

public class RecyclableAtomicInteger extends AtomicInteger
{
/**
* Atomically increments by one the current value, or return
* to zero if the value exceeds threshold
*
* @return the updated value
*/
public final int incrementAndRecycle(int threshold) {
for (;;) {
int current = get();
int next = (current + 1) % threshold;
if (compareAndSet(current, next))
return next;
}
}
}

time.c 的Java实现(从timestamp计算年月日时分秒等数值)的更多相关文章

  1. [置顶] java得到前一个月的年月日时分秒

    import java.util.Calendar; /** * 得到前一个月的年月日时分秒 * @author Mr.hu * 2013-6-28上午12:00:35 * Class Explain ...

  2. java 获取当前时间及年月日时分秒

    java代码如下: package test; import java.text.SimpleDateFormat; import java.util.Calendar; import java.ut ...

  3. java.sql.date 插入数据库没有时分秒

    java.sql.date 插入数据库没有时分秒 把java中实体类的sql.date类型改成java.sql.Timestamp类型即可 util.date 转 Timestamp: java.sq ...

  4. C#计算两个时间的时间差,精确到年月日时分秒

    喏,计算两个时间的时间差,精确到年月日时分秒 看起来比较笨的方法了,不知道有没有改进 DateTime d1 = new DateTime(2016, 4, 1, 0, 0, 0); DateTime ...

  5. java中Date无法获取数据库时分秒的问题

      数据库使用的字段是timestamp(6),在数据库看的时候明明时分秒是有的,然而通过rs.getDate()获取出来的时候时分秒就没有了,查了一下资料终于解决了,这里有一个重要的知识点,java ...

  6. java Date获取 年月日时分秒

    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 3 ...

  7. 2018.2.2 java中的Date如何获取 年月日时分秒

    package com.util; import java.text.DateFormat; import java.util.Calendar; import java.util.Date; pub ...

  8. Java输出当前的日期(年月日时分秒毫秒)

    package test.remote.tools.combine; import java.text.SimpleDateFormat; import java.util.Calendar; imp ...

  9. java日期格式(年月日时分秒毫秒)

    package test.remote.tools.combine; import java.text.SimpleDateFormat; import java.util.Calendar; imp ...

随机推荐

  1. [moka同学笔记]五、Yii2.0课程笔记(魏曦老师教程)[审核功能]

  2. FilterDispatcher已被标注为过时解决办法 &gt;&gt;&gt; FilterDispatcher &lt;&lt;&lt; is deprecated!

    一些struts2的教程都是比较早的,当我们基于较新版本的struts2来实现代码的时候,往往会出现一些问题.比如这个警告:FilterDispatcher isdeprecated! 在web.xm ...

  3. Atitit 面向对象编程(OOP)、面向组件编程(COP)、面向方面编程(AOP)和面向服务编程(SOP)的区别和联系

    Atitit 面向对象编程(OOP).面向组件编程(COP).面向方面编程(AOP)和面向服务编程(SOP)的区别和联系 1. 面向组件编程(COP) 所以,组件比起对象来的进步就在于通用的规范的引入 ...

  4. Java基础学习 -- I/O系统、流

    Java类库里有四个表示流的抽象父类:InputStream.OutputStream.Reader.Writer. 其中 InputStream 和 OutputStream 是对字节进行操作的输入 ...

  5. css3制作旋转立方体相册

    首先让我们来看一下最终效果图: 当鼠标放在图片上是介个样子滴: 是不是觉得很好看?那接下来就一起制作吧! 我个人觉得编程,首先是思路,然后是代码,一起分析一下这个效果的思路. 1.背景颜色,它属于一种 ...

  6. ADO.NET数据库参数化

    数据库参数化传递可以增强数据的安全性,但却会降低开发效率,为此创建了如下函数以解决这个问题: public static string PrepareParameter(string sql, out ...

  7. Oracle常用SQL查询(2)

    三.查看数据库的SQL 1 .查看表空间的名称及大小 select  t.tablespace_name,  round ( sum (bytes / ( 1024 * 1024 )), 0 ) ts ...

  8. Linux系统实战项目——sudo日志审计

    Linux系统实战项目——sudo日志审计   由于企业内部权限管理启用了sudo权限管理,但是还是有一定的风险因素,毕竟运维.开发等各个人员技术水平.操作习惯都不相同,也会因一时失误造成误操作,从而 ...

  9. JVM-加载,链接,初始化

    Java Virtual Machine 动态的加载,链接和初始化类和接口.那么,Class 二进制文件是怎样被 JVM 加载到内存中的?JVM 如何描述一个 Java 类?类或接口怎么才能让 JVM ...

  10. Visual Studio 2013 Update 2 RTM 发布

    今天,微软再Visual Studio Blog发布了开放Visual Studio 2013 Update 2 RTM 下载的文章. 原来安装RC版本的同志们可以直接安装,提供在线安装和ISO下载安 ...