//方案— 优点:仅使用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;
}