//方案— 优点:仅使用C标准库;缺点:只能精确到秒级
#include <time.h>
#include <stdio.h>
int main( void )
{
time_t t = time(0);
char tmp[64];
strftime( tmp, sizeof(tmp), "%Y/%m/%d %X %A 本年第%j天 %z",localtime(&t) );
puts( tmp );
return 0;
}
size_t strftime(char *strDest, size_t maxsize, const char *format, const struct tm *timeptr);
根据格式字符串生成字符串。
struct tm *localtime(const time_t *timer);
取得当地时间,localtime获取的结果由结构tm返回
返回的字符串可以依下列的格式而定:
%a 星期几的缩写。Eg:Tue
%A 星期几的全名。 Eg: Tuesday
%b 月份名称的缩写。
%B 月份名称的全名。
%c 本地端日期时间较佳表示字符串。
%d 用数字表示本月的第几天 (范围为 00 至 31)。日期
%H 用 24 小时制数字表示小时数 (范围为 00 至 23)。
%I 用 12 小时制数字表示小时数 (范围为 01 至 12)。
%j 以数字表示当年度的第几天 (范围为 001 至 366)。
%m 月份的数字 (范围由 1 至 12)。
%M 分钟。
%p 以 ''AM'' 或 ''PM'' 表示本地端时间。
%S 秒数。
%U 数字表示为本年度的第几周,第一个星期由第一个周日开始。
%W 数字表示为本年度的第几周,第一个星期由第一个周一开始。
%w 用数字表示本周的第几天 ( 0 为周日)。
%x 不含时间的日期表示法。
%X 不含日期的时间表示法。 Eg: 15:26:30
%y 二位数字表示年份 (范围由 00 至 99)。
%Y 完整的年份数字表示,即四位数。 Eg:2008
%Z(%z) 时区或名称缩写。Eg:中国标准时间
%% % 字符。
//方案二 优点:能精确到毫秒级;缺点:使用了windows API
#include <windows.h>
#include <stdio.h>
int main( void )
{
SYSTEMTIME sys;
GetLocalTime( &sys );
printf( "%4d/%02d/%02d %02d:%02d:%02d.%03d 星期%1d/n",sys.wYear,sys.wMonth,sys.wDay,sys.wHour,sys.wMinute, sys.wSecond,sys.wMilliseconds,sys.wDayOfWeek);
return 0;
}
//方案三,优点:利用系统函数,还能修改系统时间
//此文件必须是c++文件
#include<stdlib.h>
#include<iostream>
using namespace std;
void main()
{
system("time");
}
//方案四,将当前时间折算为秒级,再通过相应的时间换算即可
//此文件必须是c++文件
#include<iostream>
#include<ctime>
using namespace std;
int main()
{
time_t now_time;
now_time = time(NULL);
cout<<now_time;
return 0;
}
一:简单说明
ScheduleExecutorService接口中有四个重要的方法,其中scheduleAtFixedRate和scheduleWithFixedDelay在实现定时程序时比较方便。
下面是该接口的原型定义
java.util.concurrent.ScheduleExecutorService extends ExecutorService extends Executor
接口scheduleAtFixedRate原型定义及参数说明
public ScheduledFuture<?> scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit);
command:执行线程
initialDelay:初始化延时
period:两次开始执行最小间隔时间
unit:计时单位
public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit);
command:执行线程
initialDelay:初始化延时
period:前一次执行结束到下一次执行开始的间隔时间(间隔执行延迟时间)
unit:计时单位
二:功能示例
1.按指定频率周期执行某个任务。
初始化延迟0ms开始执行,每隔100ms重新执行一次任务。
/** * 以固定周期频率执行任务 */ public static void executeFixedRate() { ScheduledExecutorService executor = Executors.newScheduledThreadPool(1); executor.scheduleAtFixedRate( new EchoServer(), 0, 100, TimeUnit.MILLISECONDS); }间隔指的是连续两次任务开始执行的间隔。
2.按指定频率间隔执行某个任务。
初始化时延时0ms开始执行,本次执行结束后延迟100ms开始下次执行。
/** * 以固定延迟时间进行执行 * 本次任务执行完成后,需要延迟设定的延迟时间,才会执行新的任务 */ public static void executeFixedDelay() { ScheduledExecutorService executor = Executors.newScheduledThreadPool(1); executor.scheduleWithFixedDelay( new EchoServer(), 0, 100, TimeUnit.MILLISECONDS); }
3.周期定时执行某个任务。
有时候我们希望一个任务被安排在凌晨3点(访问较少时)周期性的执行一个比较耗费资源的任务,可以使用下面方法设定每天在固定时间执行一次任务。
/** * 每天晚上8点执行一次 * 每天定时安排任务进行执行 */ public static void executeEightAtNightPerDay() { ScheduledExecutorService executor = Executors.newScheduledThreadPool(1); long oneDay = 24 * 60 * 60 * 1000; long initDelay = getTimeMillis("20:00:00") - System.currentTimeMillis(); initDelay = initDelay > 0 ? initDelay : oneDay + initDelay; executor.scheduleAtFixedRate( new EchoServer(), initDelay, oneDay, TimeUnit.MILLISECONDS); }
/** * 获取指定时间对应的毫秒数 * @param time "HH:mm:ss" * @return */ private static long getTimeMillis(String time) { try { DateFormat dateFormat = new SimpleDateFormat("yy-MM-dd HH:mm:ss"); DateFormat dayFormat = new SimpleDateFormat("yy-MM-dd"); Date curDate = dateFormat.parse(dayFormat.format(new Date()) + " " + time); return curDate.getTime(); } catch (ParseException e) { e.printStackTrace(); } return 0; }
4.辅助代码
class EchoServer implements Runnable { @Override public void run() { try { Thread.sleep(50); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("This is a echo server. The current time is " + System.currentTimeMillis() + "."); } }
三:一些问题
上面写的内容有不严谨的地方,比如对于scheduleAtFixedRate方法,当我们要执行的任务大于我们指定的执行间隔时会怎么样呢?
对于中文API中的注释,我们可能会被忽悠,认为无论怎么样,它都会按照我们指定的间隔进行执行,其实当执行任务的时间大于我们指定的间隔时间时,它并不会在指定间隔时开辟一个新的线程并发执行这个任务。而是等待该线程执行完毕。
源码注释如下:
* Creates and executes a periodic action that becomes enabled first * after the given initial delay, and subsequently with the given * period; that is executions will commence after * <tt>initialDelay</tt> then <tt>initialDelay+period</tt>, then * <tt>initialDelay + 2 * period</tt>, and so on. * If any execution of the task * encounters an exception, subsequent executions are suppressed. * Otherwise, the task will only terminate via cancellation or * termination of the executor. If any execution of this task * takes longer than its period, then subsequent executions * may start late, but will not concurrently execute.根据注释中的内容,我们需要注意的时,我们需要捕获最上层的异常,防止出现异常中止执行,导致周期性的任务不再执行。
#include <stdio.h> #include <malloc.h> #include <string.h> #define MaxSize 50 #define TRUE 1 #define FALSE 0 typedef int BOOL; typedef struct student { char num[9]; char name[9]; char sex[5]; float score; }student; typedef student T ; typedef struct { int Size; int MaxList; T Element[MaxSize]; }List; List* initial() { List *lst; lst=(List *)malloc(sizeof(List)); return lst; } void CreateList(List *lst, int maxsize) { lst->Size = 0; lst->MaxList = maxsize; } BOOL Append(List *lst,T x) { if(lst->Size > lst->MaxList) { printf("Out of Data!"); return FALSE; } strcpy(lst->Element[lst->Size].num, x.num); strcpy(lst->Element[lst->Size].name, x.name); strcpy(lst->Element[lst->Size].sex, x.sex); lst->Element[lst->Size].score = x.score; lst->Size++; return TRUE; } BOOL IsFull(List* lst) { if(lst->Size==lst->MaxList) return TRUE; else return FALSE; } BOOL Insert(List* lst, int pos, T x) { int i; if ( IsFull(lst)){ printf("Overflow"); return FALSE; } if ( pos<0 || pos > lst->Size){ printf("Out of Bounds"); return FALSE; } for ( i=lst->Size-1; i>=pos; i-- ) { lst->Element[i+1] = lst->Element[i]; } strcpy(lst->Element[pos].num, x.num); //字符; strcpy(lst->Element[pos].name, x.name); strcpy(lst->Element[pos].sex, x.sex); lst->Element[pos].score = x.score; lst->Size++; return TRUE; } BOOL Remove(List* lst, int pos) { int i; if(pos>=0 && pos <= lst->Size-1) { for(i = pos; i < lst->Size-1; i++ ) { lst->Element[i] = lst->Element[i+1]; } lst->Size = lst->Size -1; } else { printf("要删除的位置不合法!\n"); } return 0; } BOOL Replace(List* lst, int pos, T x) { if(pos >= 0 && pos <= lst->Size) { lst->Element[pos] = x; printf("替换成功!\n"); } else { printf("输入的信息不合法\n"); } return 0; } void Find(List* lst, int pos) { if(pos>=0 && pos <= lst->Size-1) { printf("find it!\n"); } } void output(List *lst, int j) { printf("%-10s%-10s%-10s%6f\n",lst->Element[j].num, lst->Element[j].name, lst->Element[j].sex,lst->Element[j].score); } void Loc(List* lst, char *a) { int i; for(i = 0; i < lst->Size-1; i++) { if(!strcmp(lst->Element[i].num , a)) { output(lst, i);break; } } } void Show(List *lst) { int i; printf("数据表中记录条数为:%d\n",lst->Size); printf("____________________________________________________________________\n"); for(i=0; i < lst->Size; i++) { printf("%-10s%-10s%-10s%6f\n",lst->Element[i].num, lst->Element[i].name, lst->Element[i].sex,lst->Element[i].score); printf("____________________________________________________________________\n"); } } void input( T* stemp ) { printf("学号:"); scanf("%s", stemp->num); printf("姓名:"); scanf("%s", stemp->name); printf("性别:"); scanf("%s", stemp->sex); printf("成绩:"); scanf("%f", &stemp->score); } int main() { List *L; int i, pos, maxsize; int loc = 0; char sf; char num[10]; T* stemp; stemp = (T *)malloc(sizeof(T)); L = initial(); maxsize = MaxSize; CreateList(L, maxsize); printf("请输入所选择的功能代码:\n"); printf("1-Append 2-Show 3-Insert 4-Remove 5-Replace \n"); printf("6-find 7-Locate 0-Exit\n"); scanf("%d", &i); do{ switch(i) { case 1: printf("请输入学生信息:\n"); input(stemp); if (Append(L,*stemp)==TRUE) { printf("添加数据成功!"); } else { printf("添加数据失败!"); } break; case 2: Show(L); break; case 3: printf("您要在哪个位置插入记录?"); scanf("%d",&pos); printf("请输入您要插入的学生记录:\n"); printf("请输入学生信息:\n"); input(stemp); Insert( L, pos, *stemp ); Show(L); break; case 4: printf("请输入要删除学生的位置:\n"); scanf("%d", &loc); Remove( L, loc ); Show( L ); break; case 5: printf("请输入您要替换的位置:\n"); scanf("%d", &loc); input(stemp); Replace( L, loc, *stemp ); Show(L); break; case 6: printf("请输入要查找第几个学生的信息:\n"); scanf("%d", &loc); Find( L, loc-1 ); output(L, loc-1); break; case 7: printf("请输入要查找学生的学号:\n"); scanf("%s", num); Loc(L, num); default:break; } if (i!=0){ printf("是否继续?(Y/N)"); getchar(); scanf("%c", &sf); if (sf=='N'||sf=='n') { break; } printf("请输入所选择的功能代码:\n"); scanf("%d",&i); } }while(i); return 0; }