posts - 189,comments - 115,trackbacks - 0

软件,让世界变平


[转贴]
http://gocom.primeton.com/modules/techresource/article1075.htm
《世界是平的》作者弗里德曼


500年前哥伦布发现美洲大陆,证明地球是圆的;21世纪初美国《纽约时报》专栏作家弗里德曼来到亚洲后感慨:世界是平的!

无独有偶,经过重重筛选和征集,2008北京奥运终于选出了这样的口号:同一个世界,同一个梦想。

因为世界从没有像现在这么小过,也从来没有像现在这么近过。

几千年前,老子的梦想——小国寡民,鸡犬之声相闻,老死不相往来,轰然倒塌。

全球化的利器就是网络和软件。

其中,软件,正以不可思议的无形力量,抹平了世界。

时间是“平”的

软件让世界变平。“平”的意思一旦到了汉语中,就衍生出了丰富的含义和引申。至少,它包含了三个纬度:时间、空间和精神。

所谓时间纬度的“平”,就是企业提升效率,从传统管理转向新型管理。
因此乎,小虾米和大鲸鱼可以平起平坐了,小企业可以公然和大企业抢生意。从前的企业要发展20年才能国际化,今天创业第2天就跨国的比比皆是;中国制造和印度外包正以令人眩目的速度崛起,中国和亚洲成为新的全球化中心。
其中,企业管理类软件起到了重要的作用,它的主要功能就是科学管理,提升效率。

自18世纪产业革命以来,手工业作坊向工厂生产的方向发展,出现了制造业。随之而来,所有企业几乎无一例外地追求着基本相似的营运目标,即企业利润最大化。如何合理制订生产计划、有效控制成本、充分利用设备、管理库存等等,对企业具有生死存亡的意义。于是,各种企业管理理论和实践也就应运而生。50年代中期,计算机的商业化应用开辟了企业管理信息处理的新纪元。这对企业管理所采用的方法产生了深远的影响。

市场竞争激烈程度、市场竞争范围以及市场与客户需求变化速度,这三个因素的不断变化,推动了企业管理软件从早期的MRP经历了闭环MRP和MRPⅡ,一直发展到今天的ERP,并朝着未来的方向进一步发展。

在经历了“上ERP是找死,不上ERP是等死”这样的恐惧和犹豫之后,传统企业审慎而热情地投入了这一场管理的革命。他们失去的是传统的管理弊病,得到的,是自己和管理软件企业的共赢。



江苏雪豹集团董事长兼总经理 孙秉忠指着工厂前面的别墅说:“我们要用可以买下前面一大片房子的钱来投入雪豹信息化”



雪豹集团是一家生产各种日化用、药用喷雾泵(阀)并配套微型铝罐、塑料瓶的民营企业。这样的企业在江浙一带特别常见。

作为一个手工作坊发展起来的企业,雪豹集团的管理是传统的粗放管理。手工作业,无法实时了解订单、回款状况,而且业务繁多,时常会订单、发货出错。这导致雪豹每年都要造成三四百万元的损失。

2004年8月中旬,总经理召集所有工人,指着工厂前面的别墅说:“我们要用可以买下前面一大片房子的钱来投入雪豹信息化,要用超过10%的净资产来投入信息化!唯一的目的是使雪豹脱胎换骨,从传统的江阴民企脱胎换骨成国际一流的现代企业。”

一年之后,雪豹的信息化系统已经全面覆盖了企业的各个管理领域。雪豹有很多订单是出口的,现在他们也能实时了解最新的订单情况,国内国外,虽然差着万里,但却没有差别。

世界500强的国外企业,花了近百年的时间迈入信息时代,而江苏一个小小的民营罐头厂,一年之内也进入了信息时代的门槛。

现在,ERP不但是可以运行在电脑上的,还可以是运行在手机中的。燕京啤酒的经销商每天都可以将销量信息直接发送总部,这些信息可以帮助该公司及时了解产品的销售、库存状况,从而合理安排生产、货物调配及运输业务。
除了企业管理软件之外,协同软件也在抹平时间的纬度中大放异彩。
时间,似乎在后来者的面前一下子跑了起来,用几年的时间去追赶近百年的历程,然后,把他们一同带入了市场竞争的起跑线。

空间是“平”的

所谓空间纬度的“平”,就是没有了空间的阻隔,千里之外,近在眼前。

即时通讯软件改变了世界。即时通讯的历史并不久远,但是它一诞生,就立即受到网民的喜爱,并风靡全球。在它的发展史上,以色列人功不可没。1996年7月,四位以色列籍的年轻人成立了Mirabilis公司,同年11月,推出了全世界第一款即时通讯软件ICQ,取意为“我在找你”——“ISeekYou”,简称ICQ。当时开发的这款即时通讯软件,其目的很简单,只是为了连接在同一个服务器上的用户能够相互交流。可谁也没有想到,就是这样一个小小的软件,改变了整个互联网的发展,成为许多商家你争我夺的商业地盘。

即时通讯软件的优点是毋庸置疑的,只要通信双方拥有同样的软件,只需打开小小的窗口就能与对方进行通信。不管对方是在世界的哪一端。不知不觉间,即时通讯软件成了人们在网上联络的大红大紫的宠儿,几乎每个网上用户都有了自己的即时通讯账号,甚至,即时通讯的账号成为了网络上每个用户的必备ID。

坐地日行八万里,巡天遥看一千河,从神话中成为了现实。

1999年,腾讯公司创始人马化腾将中国的第一个即时通讯工具Oicq推向了互联网舞台。六年间,腾讯小企鹅的飞速发展成为互联网应用中最引人注目的现象之一。今天,每个上网的人几乎必备腾讯QQ、雅虎通、MSN等即时通讯软件。随着腾讯QQ在中国的巨大成功,互联网的本质得到人们更多认识,一个巨大的以即时通讯为核心的互联网应用产业也在逐渐形成之中。

即时通讯的崛起,不仅仅给人们带来了通信的方便,更重要的是它正渗入人们生活的点点滴滴,改变了人们的生活。至此,即时通讯产品已不再被定义为一个简单的沟通工具,而是一个信息资讯、交流互动、休闲娱乐的平台,语音、视频、音乐点播、网络游戏、在线交易、BBS、blog、信息共享等新的应用都基于这个平台开展,并正以前所未有的速度改变着人们的生活方式,也创造着更广阔的互联网产业前景。

精神是“平”的

所谓精神纬度的“平”,就是精神上的平等。

杰佛逊在《独立宣言》中说,人人生而平等。而现实世界中,人其实生而不平等,但软件却可以让世界是公平而开放的,而且一切皆有可能。

这种“平”,首先是一种改变国家软件产业的平等。
面对软件游戏规则被国外掌握的困境,只要敢想,就可以找到平等对话的机会。

长期以来,中国软件在与国外软件的竞争中往往处于被动,缺乏战略上的竞争优势。无论从国家安全还是产业角度,中国都需要一场场在软件领域的胜利突围。这不仅是必要的,而且是必须的。

面向构件就是其中一种选择。面向构件是软件美国在痛定思痛之后不得不作出的选择。而中国在此方面有着无以伦比的优势。因为我们无需推倒重来,我们没有那么多的废墟和负担,我们有的,只是建造一个美丽新世界的勇气和果敢。

面向构件的模式,可以让中国在技术上几乎处在最领先的起跑线上。本土的软件企业理当有实力解开困扰很多中国企业的软件死结,同时在解开中国企业级软件死结的背后所展现的一个重大机会似乎更让人激动:面向构件的应用基础平台完全可以在这个领域形成本土的企业群,并成就中国的软件产业的国际大企业梦想。

这种“平”,还是一种打破垄断力量的平等。

当诺大一个软件世界掌握在一家公司之手,为他所左右时,软件开发人员想不通,自己开发的东西竟然成了的垄断工具,成了软件业发展的枷锁。为了改变这一局势,开发人员自动成立了“开放源代码”组织,旨在倡导“自由开放”的社会精髓,更加集中地促进软件业的快速发展。Linux就是最杰出的代表,几乎成了开放源代码的代名词。Linux以其自由开放的特性而深得大家的喜爱。当“小企鹅”在大家的一片欢呼声中茁壮成长时,迎面而来的就是一个纷繁复杂的商业社会。

开放源代码一出世就与知识产权保护格格不入,倡导自由开放的“开源”在倍受世人宠爱的同时,其成长注定要经历急风暴雨,除非它停留在口头上或抽屉里。然而,后面的假设对Linux来说已经时过境迁,企鹅已经成为了时代的勇士。这也许是时代的一种必然选择,因为市场经济必将打破各种垄断,无论这种垄断是国有的还是行业的;无论打破垄断的方式是私营还是公有,是个人还是国家,社会都将朝着公平竞争的时代迈进。

Linux受到的支持越来越多,从倡导、支持、拥护到命令、立法、自创;从欧洲到亚洲再到非洲;从个人到公司再到政府,甚至包括不信奉市场经济原则的国家,都在立法规定或行政命令,要求政府必须使用开源软件。

尽管Linux和开放源代码算不上是一种突破性的技术,Linux称其量也只是Unix的一种变种或分枝,但开放源代码打破了传统的软件观念,开创了一种全新的软件模式。Linux的突破作用不仅改变了整个软件经济格局,更是带来了自由开放公平的精神,它对整个社会和人类的贡献不亚于一项伟大技术的成就。
这种“平”,更是一种承载弱势群体梦想的平等。

当一个贫困地区的孩子,也能通过视频、音频软件接受最新的教育,通过在线考试系统提交试卷接受教育考评,软件,就是他走出大山的明灯。当一个盲人通过读屏软件也能畅想大千世界,遨游网络的时候,软件,就是他看向世界的双眼。当残疾人士坐在轮椅上,一样能通过photoshop、flash等软件设计作品,自力更生甚至创业时,软件是他走向成功人生的双足。

不敢想的可以想,不敢做的可以做,只要你想,一切皆有可能。几乎所有的工具软件都承载了弱势群体自由飞翔的翅膀。

真实的世界在有些人眼里也许不是平的,它可能是倾斜的,资源的偏向有很大的差距。但是软件的力量正在蔓延开去,如洪流一样席卷全球,而且,它正是消除资源分配不公的良药。

弗里德曼说,小时候爸妈说:“儿子啊,乖乖把饭吃完,因为中国跟印度的小孩没饭吃。”现在他自己则说:“女儿啊,乖乖把书念完,因为中国跟印度的小孩正等着抢你的饭碗。”

美国的孩子,和中国、印度的孩子没了差别,这种对等,就是支撑世界进一步全球化的真正信仰。

尼采说,两山最短的距离,是山峰与山峰之间的距离。

那么他一定没想到今天,世界最短的距离,只是一个软件安装时间的距离。



Java的时间处理(续<计算Java时间>)

学习在java中计算基本的时间段
概述
如果你知道怎样在java中使用日期,那么使用时间和它才不多一样简单。这篇文章告诉你怎样把他们的差别联系起来。Robert Nielsen还告诉你怎样使用java来计算抵达航班和制造过程的时间。
作者:Robert Nielsen
翻译:Cocia Lin



这篇文章是在我发表过的<计算Java时间>(译者:已经翻译完成)的基础上的。在这里,我列出那篇文章几个你应该熟悉得关键点。如果这几点你不太清楚,我建议你读一下<计算Java时间>,了解一下。
1. Java计算时间依靠1970年1月1日开始的毫秒数.
2. Date类的构造函数Date()返回代表当前创建的时刻的对象。Date的方法getTime()返回一个long值在数值上等于1970年1月1日之前或之后的时刻。
3. DateFormat类用来转换Date到String,反之亦然。静态方法getDateInstance()返回DateFormat的缺省格式;getDateInstance(DateFormat.FIELD)返回指定的DateFormat对象格式。Format(Date d)方法返回String表示日期,例如"January 1,2002."反过来,parse(String s)方法返回以参数字符串表示的Date对象。
4. format()方法返回的字符串格式根据不同地区的时间设置而有所不同。
5. GregorianCalendear类有两个重要的构造函数:GregorianCalerdar(),返回代表当前创建时间的对象;GregorianCalendar(int year,int month,int date)返回代表任意日期的对象。GregorianCalendar类的getTime()方法返回日期对象。Add(int field,int amount)方法通过加或减时间单位,象天数,月数或年数来计算日期。
GregorianCalendar和 时间
两个GregorianCalendar的构造函数可以用来处理时间。前者创建一个表示日期,小时和分钟的对象:

GregorianCalendar(int year, int month, int date, int hour, int minute)

第二个创建一个表示一个日期,小时,分钟和秒:

GregorianCalendar(int year, int month, int date, int hour, int minute, int second)

首先,我应该提醒一下,每一个构造函数需要时间信息中的日期信息(年,月,日)。如果你想说2:30 p.m.,你必须指出日期。
同样,每一个GregorianCalendar构造函数创建一个在时间上使用毫秒计算的对象。所以,如果你的构造函数只提供年,月,日参数,那小时,分钟,秒和毫秒的值将被置0.
DateFormat和时间
你可以使用静态方法getDateTimeInstance(int dateStyle,int timeStyle)来建立DateFormat对象来显示时间和日期。这个方法表明你想要的日期和时间格式。如果你喜欢使用缺省格式,可以使用getDateTimeInstance()来代替它。
你可以使用静态方法getTimeInstance(int timeStyle)创建DateFormat对象来显示正确的时间。
下面的程序示范了getDateTimeInstance()和getTimeInstance()怎样工作:

import java.util.*;
import java.text.*;

public class Apollo {
public static void main(String[] args) {
GregorianCalendar liftOffApollo11 = new GregorianCalendar(1969, Calendar.JULY, 16, 9, 32);
Date d = liftOffApollo11.getTime();
DateFormat df1 = DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM);
DateFormat df2 = DateFormat.getTimeInstance(DateFormat.SHORT);
String s1 = df1.format(d);
String s2 = df2.format(d);
System.out.println(s1);
System.out.println(s2);
}
}

在我的电脑上,上面的程序显示如下:

Jul 16, 1969 9:32:00 AM
9:32 AM
(输出根据你所在得地区有所不同)

计算时间间隔
你可能有时需要计算过去的时间;例如,给你开始和结束时间,你想知道制造流程的持续时间。一个出租公司按小时或天数出租东西,计算时间对他们也很有用。同样的,在金融界,经常需要计算重要的支付时间。
将问题复杂化,人类至少是用两种方法计算时间。你可以说一天已经结束当24小时过去了,或者日历从今天翻到明天。我们将讨论我们想到的这两种情况。
时间段,情况 1:严格时间单位
在这种情况中,只有24小时过去,这天才过去,60分钟过去,这个小时才过去,60秒过去,这个分钟才过去,以此类推。在这个方法中,23小时的时间将被认为是0天。
使用这种方法计算时间段,你从计算过去的毫秒开始。为了做到这一点,首先转换每个日期为从1970年1月1日起得毫秒数。你可以从第二个毫秒值中减去第一个毫秒值。这里有一个简单的计算:

import java.util.*;

public class ElapsedMillis {
public static void main(String[] args) {
GregorianCalendar gc1 = new GregorianCalendar(1995, 11, 1, 3, 2, 1);
GregorianCalendar gc2 = new GregorianCalendar(1995, 11, 1, 3, 2, 2);
// the above two dates are one second apart
Date d1 = gc1.getTime();
Date d2 = gc2.getTime();
long l1 = d1.getTime();
long l2 = d2.getTime();
long difference = l2 - l1;
System.out.println("Elapsed milliseconds: " + difference);
}
}

上面的程序打印如下:

Elapsed milliseconds: 1000

这个程序也带来一点混淆。GregorianCalendar类的getTime()返回一个Date对象,Date类的getTime()方法返回从1970年1月1日到这个时间的long类型的毫秒数值。虽然他们的方法名字相同,返回值却不一样!
下面的程序片断用简单的整数除法转换毫秒到秒:

long milliseconds = 1999;
long seconds = 1999 / 1000;

这种方法舍去小数部分转换毫秒到秒,所以1,999毫秒等于1秒,2,000毫秒等于2秒。
计算更大的单位-例如天数,小时和分钟-给定一个时间数值,可以使用下面的过程:
1. 计算最大的单位,减去这个数值的秒数
2. 计算第二大单位,减去这个数值的秒数
3. 重复操作直到只剩下秒
例如,如果你的时间的10,000秒,你想知道这个数值相应的是多少小时,多少分钟,多少秒,你从最大的单位开始:小时。10,000除以3600(一个小时的秒数)得到小时数。使用整数除法,答案是2小时(整数除法中小数舍去)计算剩下的秒数,10,000-(3,600 x 2) = 2,800秒。所以你有2小时和2,800秒。
将2,800秒转换成分钟,2,800除以60。使用整数除法,答案是46。2,800 - (60 x 46) = 40秒。最后答案是2小时,46分,40秒。
下面的Java程序使用上面的计算方法:

import java.util.*;

public class Elapsed1 {
public void calcHMS(int timeInSeconds) {
int hours, minutes, seconds;
hours = timeInSeconds / 3600;
timeInSeconds = timeInSeconds - (hours * 3600);
minutes = timeInSeconds / 60;
timeInSeconds = timeInSeconds - (minutes * 60);
seconds = timeInSeconds;
System.out.println(hours + " hour(s) " + minutes + " minute(s) " + seconds + " second(s)");
}

public static void main(String[] args) {
Elapsed1 elap = new Elapsed1();
elap.calcHMS(10000);
}
}

输出结果如下:

2 hour(s) 46 minute(s) 40 second(s)

上面的程序甚至在时间少于一个小时也可以正确的计算小时数。例如,你用上面的程序计算1,000秒,输出入下:
0 hour(s) 16 minute(s) 40 second(s)
举一个现实世界的例子,下面的程序计算阿波罗11飞到月球使用得时间:

import java.util.*;

public class LunarLanding {

public long getElapsedSeconds(GregorianCalendar gc1, GregorianCalendar gc2) {
Date d1 = gc1.getTime();
Date d2 = gc2.getTime();
long l1 = d1.getTime();
long l2 = d2.getTime();
long difference = Math.abs(l2 - l1);
return difference / 1000;
}

public void calcHM(long timeInSeconds) {
long hours, minutes, seconds;
hours = timeInSeconds / 3600;
timeInSeconds = timeInSeconds - (hours * 3600);
minutes = timeInSeconds / 60;
System.out.println(hours + " hour(s) " + minutes + " minute(s)" );
}

public static void main(String[] args) {
GregorianCalendar lunarLanding = new GregorianCalendar(1969, Calendar.JULY, 20, 16, 17);
GregorianCalendar lunarDeparture = new GregorianCalendar(1969, Calendar.JULY, 21, 13, 54);
GregorianCalendar startEVA = new GregorianCalendar(1969, Calendar.JULY, 20, 22, 56);
GregorianCalendar endEVA = new GregorianCalendar(1969, Calendar.JULY, 21, 1, 9);

LunarLanding apollo = new LunarLanding();

long eva = apollo.getElapsedSeconds(startEVA, endEVA);
System.out.print("EVA duration = ");
apollo.calcHM(eva);

long lunarStay = apollo.getElapsedSeconds(lunarLanding, lunarDeparture);
System.out.print("Lunar stay = ");
apollo.calcHM(lunarStay);
}
}

上面程序输出如下:

EVA duration = 2 hour(s) 13 minute(s)
Lunar stay = 21 hour(s) 37 minute(s)

目前为止,我们计算的基础公式是这样的:1分钟=60秒,1小时=60分,1天=24小时。
"1个月=?天,1年=?天"怎么办?
月份的天数有28,29,30,31;一年可以是365或366天。因此,当你试图计算严格单位的月份和年时,问题就产生了。例如,如果你使用月份的平均天数(近似30.4375),并且计算下面的时间间隔:

* July 1, 2:00 a.m. to July 31, 10:00 p.m.
* February 1, 2:00 a.m. to February 29, 10:00 p.m.

第一个计算结果是1个月;第二个结果是0个月!
所以,在计算严格单位时间的月份和年份是要想好。
时间段,情况 2:时间单位变化
时间单位的变化相当的简单:如果你要统计天数,你可以简单的统计日期变化次数。例如,如果某事15日开始,17日结束,经过2天。(日期先是便到16,再到17)同样的,一个步骤下午3:25开始,4:10 p.m结束,历时1个小时,因为小时数值变了一次(从3到4)。
图书馆经常使用这种习惯计算时间。例如,如果你从图书馆接一本书,我不能占有这本书最少24小时,会认为图书馆这样才给你算一天。而是,我的账号上记录我借书的日期。日期以变成下一天,我就已经结这本书一天了,即使总计不足24小时。
当使用单位的变化来计算时间段,通常感觉计算的时间没有多于一个时间单位。例如,如果9:00 p.m.我借了一本图书馆的书,第二天中午还回去,我能算出我借了这本书一天了。可是,有一种感觉在问:"1天和几个小时呢?"这本说总计借出15个小时,答案是一天还差9个小时呢?因此,这篇文章里,我将以一个时间单位变化计算时间。
单位变化的时间算法
这是你怎样计算两个日期的时间变化:
1. 制作两个日期的拷贝。Close()方法能制作拷贝。
2. 使用日期拷贝,将所有的小于时间单位变化的部分设置成它的最小单位。例如,如果计算天数,那么将小时,分钟,秒和毫秒设置成0。这种情况中,使用clear()方法将时间值设置称他们各自的最小值。
3. 取出较早的日期,将你要计算的单位加1,重复直到两个日期相等。你加1的次数就是答案。可以使用before()和after()方法,他们返回boolean值,来判断是否一个日期在另一个日期之前或之后。
下面的类的方法用来计算天数和月数。

import java.util.*;

public class ElapsedTime {

public int getDays(GregorianCalendar g1, GregorianCalendar g2) {
int elapsed = 0;
GregorianCalendar gc1, gc2;

if (g2.after(g1)) {
gc2 = (GregorianCalendar) g2.clone();
gc1 = (GregorianCalendar) g1.clone();
}
else {
gc2 = (GregorianCalendar) g1.clone();
gc1 = (GregorianCalendar) g2.clone();
}

gc1.clear(Calendar.MILLISECOND);
gc1.clear(Calendar.SECOND);
gc1.clear(Calendar.MINUTE);
gc1.clear(Calendar.HOUR_OF_DAY);

gc2.clear(Calendar.MILLISECOND);
gc2.clear(Calendar.SECOND);
gc2.clear(Calendar.MINUTE);
gc2.clear(Calendar.HOUR_OF_DAY);

while ( gc1.before(gc2) ) {
gc1.add(Calendar.DATE, 1);
elapsed++;
}
return elapsed;
}

public int getMonths(GregorianCalendar g1, GregorianCalendar g2) {
int elapsed = 0;
GregorianCalendar gc1, gc2;

if (g2.after(g1)) {
gc2 = (GregorianCalendar) g2.clone();
gc1 = (GregorianCalendar) g1.clone();
}
else {
gc2 = (GregorianCalendar) g1.clone();
gc1 = (GregorianCalendar) g2.clone();
}

gc1.clear(Calendar.MILLISECOND);
gc1.clear(Calendar.SECOND);
gc1.clear(Calendar.MINUTE);
gc1.clear(Calendar.HOUR_OF_DAY);
gc1.clear(Calendar.DATE);

gc2.clear(Calendar.MILLISECOND);
gc2.clear(Calendar.SECOND);
gc2.clear(Calendar.MINUTE);
gc2.clear(Calendar.HOUR_OF_DAY);
gc2.clear(Calendar.DATE);

while ( gc1.before(gc2) ) {
gc1.add(Calendar.MONTH, 1);
elapsed++;
}
return elapsed;
}
}

你可以在上面的类中补充另外的方法来处理小时和分钟。同样,计算时间段的算法能更高效一些,尤其是时间相隔很长。可是,作为介绍目的,这个算法有短小和简单的优势。
下面的例子使用ElapsedTime类来计算两个日期之间的天使,而后是月数:

import java.util.*;

public class Example {
public static void main(String[] args) {
GregorianCalendar gc1 = new GregorianCalendar(2001, Calendar.DECEMBER, 30);
GregorianCalendar gc2 = new GregorianCalendar(2002, Calendar.FEBRUARY, 1);

ElapsedTime et = new ElapsedTime();
int days = et.getDays(gc1, gc2);
int months = et.getMonths(gc1, gc2);

System.out.println("Days = " + days);
System.out.println("Months = " + months);
}
}

当计算时,上面的程序可能有用,例如,最近的航班。它显示下面的输出:

Days = 33
Months = 2

(OK,关于航班的计算有些夸张;这个天数算法很适合像图书馆借书这样的应用,你看到了她怎样工作)
告诫
在进行时间工作时要谨慎:你看到的时间段的例子,你精确仔细的考虑非常重要。本文介绍了两种通常计算时间段的想法,但是人们能想到的时间段的计算方法仅仅受到人类想象力的限制。
所以,当写一个Java程序的时候,确信你的精确度能让使用和以来这些程序的人满意。同样,彻底的测试程序对处理时间的程序非重重要。
总结
本文是在我的前一篇文章 Java时间计算介绍怎样使用GregorianCalendar 和 DateFormat类处理时间问题的基础上的。你已经看到了两种方法来思考时间段问题和两种相应的途径使用Java来处理时间问题。这里提供的信息,很基础,提供给你一个在Java中处理时间问题的有力工具。

关于作者
Robert Nielsen是SCJP。他拥有硕士学位,专攻计算机教育,并且在计算机领域执教多年。他也在各样的杂志上发表过很多计算机相关的文章。
关于译者
Cocia Lin(cocia@163.com)是程序员。它拥有学士学位,现在专攻Java相关技术,刚刚开始在计算机领域折腾。



java类Timer和TimerTask的使用
宽 发表于 2007-2-2 10:15:00

这两个类使用起来非常方便,可以完成我们对定时器的绝大多数需求

     Timer类是用来执行任务的类,它接受一个TimerTask做参数

     Timer有两种执行任务的模式,最常用的是schedule,它可以以两种方式执行任务:1:在某个时间(Data),2:在某个固定的时间之后(int delay).这两种方式都可以指定任务执行的频率.看个简单的例子:



import java.io.IOException;
import java.util.Timer;

public class TimerTest {
       
    
public static void main(String[] args){
        Timer timer 
= new Timer();
        timer.schedule(
new MyTask(), 10002000);//在1秒后执行此任务,每次间隔2秒,如果传递一个Data参数,就可以在某个固定的时间执行这个任务.
        
while(true){//这个是用来停止此任务的,否则就一直循环执行此任务了
            
try {
                
int ch = System.in.read();
                
if(ch-'c'==0){
                    timer.cancel();//使用这个方法退出任务
                    
                }

            }
 catch (IOException e) {
                
// TODO Auto-generated catch block
                e.printStackTrace();
            }

        }

    }

    
    
    
static class MyTask extends java.util.TimerTask{

        @Override
        
public void run() {
            
// TODO Auto-generated method stub
            System.out.println("________");
        }

    }

    
    
    
    
}



    如果你使用的是JDK 5+,还有一个scheduleAtFixedRate模式可以用,在这个模式下,Timer会尽量的让任务在一个固定的频率下运行,举例说明:在上面的例子中,我们想让MyTask在1秒钟后,每两秒钟执行一次,但是因为java不是实时的(其实java实时性很差.....),所以,我们在上个程序中表达的原义并不能够严格执行.如果我们调用的是scheduleAtFixedRate,那么,Timer会尽量让你的Task执行的频率保持在2秒一次.运行上面的程序,假设使用的是scheduleAtFixedRate,那么下面的场景就是可能的:1秒钟后,MyTask 执行一次,因为系统繁忙,之后的2.5秒后MyTask 才得以执行第二次,然后,Timer记下了这个延迟,并尝试在下一个任务的时候弥补这个延迟,那么,1.5秒后,MyTask 将执行的三次."以固定的频率而不是固定的延迟时间去执行一个任务"

果然很方便吧^_^

 

 

下面给出一个复杂点的例子,其中告诉大家怎么退出单个TimerTask,怎么退出所有Task

package MyTimerTest;

import java.io.IOException;
import java.util.Timer;


/*
 * 本类给出了使用Timer和TimerTaske的主要方法,其中包括定制任务,添加任务
 * 退出任务,退出定时器.
 * 因为TimerTask的status域是包级可访问的,所以没有办法在java.util.包外
 * 得到其状态,这对编程造成一些不便 .我们不能判断某个Task的状态了.
 * 
 
*/


public class TimerTest {

    
public static void main(String[] args) {
        Timer timer 
= new Timer();
        MyTask myTask1 
= new MyTask();
        MyTask myTask2 
= new MyTask();
        myTask2.setInfo(
"myTask-2");
        timer.schedule(myTask1, 
10002000);
        timer.scheduleAtFixedRate(myTask2, 
20003000);
        
while (true{
            
try {
                
byte[] info = new byte[1024];
                
int len = System.in.read(info);
                String strInfo 
= new String(info, 0, len, "GBK");//从控制台读出信息
                if (strInfo.charAt(strInfo.length() - 1== ' '{
                    strInfo 
= strInfo.substring(0, strInfo.length() - 2);
                }

                
if (strInfo.startsWith("Cancel-1")) {
                    myTask1.cancel();
//退出单个任务
                    
// 其实应该在这里判断myTask2是否也退出了,是的话就应该break.但是因为无法在包外得到
                    
// myTask2的状态,所以,这里不能做出是否退出循环的判断.
                }
 else if (strInfo.startsWith("Cancel-2")) {
                    myTask2.cancel();
                }
 else if (strInfo.startsWith("Cancel-All")) {
                    timer.cancel();
//退出Timer
                    break;
                }
 else {
                    
// 只对myTask1作出判断,偷个懒^_^
                    myTask1.setInfo(strInfo);
                }

            }
 catch (IOException e) {
                
// TODO Auto-generated catch block
                e.printStackTrace();
            }

        }

    }


    
static class

怎么在后台得到用户操作的当前时间

1:引如包(java自带的)

import java.util.Date;

import java.text.SimpleDateFormat;

 

2代码

Date nowTime=new Date();

              SimpleDateFormat m=new SimpleDateFormat("yyyyMMddHH");

              System.out.println("时间等于=="+nowTime.toLocaleString());

             

              String mmmm=m.format(nowTime);

              System.out.println("====="+mmmm);

posted on 2007-04-02 19:33 MEYE 阅读(701) 评论(0)  编辑  收藏

只有注册用户登录后才能发表评论。


网站导航: