android-获取网络时间、获取特定时区时间、时间同步的方法

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

android-获取⽹络时间、获取特定时区时间、时间同步的
⽅法
最近整理出android-获取⽹络时间、获取特定时区时间、时间同步的⽅法。

具体如下:
⽅法⼀:
SimpleDateFormat dff = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
dff.setTimeZone(TimeZone.getTimeZone("GMT+08"));
String ee = dff.format(new Date());
这个⽅法获取的结果是24⼩时制的,⽉份也正确。

这个⽅法不随⼿机时间的变动⽽变动。

也就是说,即使⼿机设置成别的时区,不是东⼋区,这个⽅法返回的也照样是北京时间这正是我在做项⽬的时候⽤到的⽅法!!彻底解决项⽬需求!
⽅法⼆:
Calendar calendar = Calendar.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat("dd-MMM-yyyy hh:mm:ss");
sdf.setTimeZone(TimeZone.getTimeZone("GMT+8"));
String rt = sdf.format(calendar.getTime());
这个⽅法获取的结果是不是24⼩时制的,⽉份也正确。

⽅法三:
public static String getLocalDatetimeString(String local) {
Calendar cal = new GregorianCalendar(TimeZone.getTimeZone(local));
cal.setTimeInMillis(Calendar.getInstance().getTimeInMillis());
String date = cal.get(Calendar.YEAR) + "-" + (cal.get(Calendar.MONTH) + 1) + "-" + cal.get(Calendar.DAY_OF_MONTH);
String time = cal.get(Calendar.HOUR_OF_DAY) + ":" + cal.get(Calendar.MINUTE) + ":" + cal.get(Calendar.SECOND);
return date + " " + time;
}
⽅法调⽤:
String tt = getLocalDatetimeString("GMT+8");
代码⾥也看出来了,这个在⽉份上加了⼀个1, 24⼩时制
以上三种⽅法验证如下:
import java.sql.Time;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.TimeZone;
public class TimeTest {
/**
* @param args
*/
public static void main(String[] args) {
method1();
method2();
method3();
}
static void method1(){
SimpleDateFormat dff = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
dff.setTimeZone(TimeZone.getTimeZone("GMT+08"));
String ee = dff.format(new Date());
System.out.println("ee="+ee);
}
static void method2(){
Calendar calendar = Calendar.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat("dd-MMM-yyyy hh:mm:ss");
sdf.setTimeZone(TimeZone.getTimeZone("GMT+8"));
String rt = sdf.format(calendar.getTime());
System.out.println("TimeTest.method2() rt="+rt);
}
static void method3(){
String local = "GMT+8";
Calendar cal = new GregorianCalendar(TimeZone.getTimeZone(local));
cal.setTimeInMillis(Calendar.getInstance().getTimeInMillis());
String date = cal.get(Calendar.YEAR) + "-" + (cal.get(Calendar.MONTH) + 1) + "-" + cal.get(Calendar.DAY_OF_MONTH);
String time = cal.get(Calendar.HOUR_OF_DAY) + ":" + cal.get(Calendar.MINUTE) + ":" + cal.get(Calendar.SECOND);
System.out.println("TimeTest.method3() date="+date+",time="+time);
}
}
结果如下:
本⼈采⽤的是第⼀种⽅法,因为第⼀种⽅法的时间是不随⼿机时间的设置⽽改变。

第⼆种⽅法也是可以的,不过时间⼩时是12进制。

第四种⽅法:
⽹上还有这种⽅法获取时间:
URL url=new URL("");//取得资源对象
URLConnection uc=url.openConnection();//⽣成连接对象
uc.connect(); //发出连接
long ld=uc.getDate(); //取得⽹站⽇期时间
Date date=new Date(ld); //转换为标准时间对象
//分别取得时间中的⼩时,分钟和秒,并输出
System.out.print(date.getHours()+"时"+date.getMinutes()+"分"+date.getSeconds()+"秒");
这种⽅式需要开启⼀个线程获取时间,同时也存在着⼀种风险就是由于⽹络问题,获取不到响应的问题。

还有⼀个重要的问题件就是这个时间的获取会随着⼿机时区的改变⽽改变。

⽅法五:
通过⽹络或者GPS的⽅式。

代码:
LocationManager locMan = (LocationManager) this.getSystemService(MainActivity.LOCATION_SERVICE);
//获取最近⼀次知道的时间
long networkTS = locMan.getLastKnownLocation(WORK_PROVIDER).getTime();
或者实时的获取时间:
locMan.requestLocationUpdates(WORK_PROVIDER, 0, 0, this); //获取当前时间
当我们使⽤requestLocationUpdates时,我们需要实现LocationListener接⼝。

在LocationListen的回调onLocationChanged当中获取时间
@Override
public void onLocationChanged(Location location) {
// TODO Auto-generated method stub
long time = location.getTime();
Date date = new Date(time);
System.out.println(time + " NETWORK_PROVIDER " + date);
// System.out.println(STANDARD_TIME + " ");
}
这种⽅式是利⽤⼿机定位系统进⾏时间的获取,但是这种⽅式会随着⼿机的设置的时区的变动⽽改变。

第四种⽅式和第五种⽅式,我都在⼿机端进⾏了验证,可以正常获取时间。

⽅式是没有问题的。

既然有这么多⽅法,⼤家看着那种⽅式适合⾃⼰的需求,选择相应的⽅法。

我还是推荐第⼀种⽅法!简单实⽤^_^
今天再在本⽂基础上补充⼀些内容。

现在我的项⽬中有这样⼀种需求:就是播放视频的时候,特别是监控视频,我想要有时间限制,在⼀定时间内可以观看,超出设置的时间,不能观看。

Android端对于这样的需求,上⾯的⼏种⽅法都不⾏了,因为上⾯的⽅法都跟⼿机系统有关系了,当我改变⼿机系统的时间,时区等都会造成获取的时间不对应,跟服务器时间不对。

怎么办呢?有办法
我是这样做的,当获取到信息的时候,⽐如视频节点信息的时候,服务器顺带着把服务器当前的时间返回来,有了服务器的时间,剩下的我就利⽤⽤户操作的时间间隔,加上服务器的时间不就是⼿机所在地当前的时间吗?
那么时间间隔怎么算呢?请看下⾯的SystemClock类⼏个⽅法:
1、System.currentTimeMillis()是⼀个标准的“墙”时钟(时间和⽇期),表⽰从纪元到现在的毫秒数。

该墙时钟能够被⽤户或电话⽹络(见setCurrentTimeMillis(long))设置,所以该时间可能会向前或向后不可预知地跳越。

该时钟应该仅仅被使⽤在当现实世界的对应的⽇期和时间是重要的情况,例如⼀个⽇历或闹钟应⽤程序。

⽽间隔时间和经过时间应该使⽤不同的时钟。

如果你使⽤System.currentTimeMillis(),可以考虑监听ACTION为ACTION_TIME_TICK、 ACTION_TIME_CHANGED、
ACTION_TIMEZONE_CHANGED 的⼴播去监听时间变化。

2、uptimeMillis()表⽰⾃系统启动时开始计数,以毫秒为单位。

返回的是从系统启动到现在这个过程中的处于⾮休眠期的时间。

当系统进⼊深度睡眠时(CPU关闭,设备变⿊,等待外部输⼊装置)该时钟会停⽌。

但是该时钟不会被时钟调整,闲置或其他节能机所影响。

这是⼤多数间隔时间的基本点,例如Thread.sleep(millls)、Object.wait(millis)和System.nanoTime()。

该时钟被保证是单调的,适⽤于检测不包含休眠的间隔时间的情况。

⼤多数的⽅法接受⼀个时间戳的值除了uptimeMillis()时钟。

3、elapsedRealtime() and elapsedRealtimeNanos() 返回系统启动到现在的时间,包含设备深度休眠的时间。

该时钟被保证是单调的,即使CPU在省电模式下,该时间也会继续计时。

该时钟可以被使⽤在当测量时间间隔可能跨越系统睡眠的时间段。

有⼏种机制控制事件发⽣的时间:
1、标准的⽅法像Thread.sleep(millis) 和 Object.wait(millis)总是可⽤的,这些⽅法使⽤的是uptimeMillis()时钟,如果设备进⼊深度休眠,剩余的时间将被推迟直到系统唤醒。

这些同步⽅法可能被Thread.interrupt()中断,并且你必须处理InterruptedException异常。

2、SystemClock.sleep(millis)是⼀个类似于Thread.sleep(millis)的实⽤⽅法,但是它忽略InterruptedException异常。

使⽤该函数产⽣的延迟如果你不使⽤Thread.interrupt(),因为它会保存线程的中断状态。

3、Handler可以在⼀个相对或者绝对的时间设置异步回调,Handler类对象也使⽤uptimeMillis()时钟,⽽且需要⼀个loop(经常出现在GUI程序中)。

4、AlarmManager可以触发⼀次或重复事件,即使设备深度休眠或者应⽤程序没有运⾏。

事件可以选择⽤ currentTimeMillis或者elapsedRealtime()(ELAPSED_REALTIME)来设置时间,当事件发⽣会触发⼀个⼴播。

⽅法:
1、public static long currentThreadTimeMillis () 返在当前线程运⾏的毫秒数。

2、public static long elapsedRealtime () 返回系统启动到现在的毫秒数,包含休眠时间。

3、public static long elapsedRealtimeNanos () 返回系统启动到现在的纳秒数,包含休眠时间。

4、public static boolean setCurrentTimeMillis (long millis) 设置当前的”墙”时间,要求调⽤进程有许可权限。

返回是否成功。

5、public static void sleep (long ms) 等待给定的时间。

和Thread.sleep(millis)类似,但是它不会抛出InterruptedException异常。

事件被推迟到下⼀个中断操作。

该⽅法直到指定的时间过去才返回。

6、public static long uptimeMillis () 返回系统启动到现在的毫秒数,不包含休眠时间。

就是说统计系统启动到现在的⾮休眠期时间。

这些⽅法⼤家看看就知道啦。

剩下的就是计算事件间隔了:
public static long elapsedRealtime () 返回系统启动到现在的毫秒数,包含休眠时间
这个⽅法就可以计算从服务器返回时间到⽤户操作,播放视频这⼀段时间的时间间隔。

有个这个不就可以做到时间不受⼿机系统的限制了吗?
/**
*
* @param ts 形如yyyy-MM-dd hh:mm:ss
* @param intervalTime long类型
* @return String HH:mm:ss
*/
@SuppressLint("SimpleDateFormat")
public static String getTime(String ts,long intervalTime){
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
Timestamp t=null;
String tt="";
try {
t = new Timestamp(format.parse(ts).getTime());
long ss = t.getTime();
long st = ss+intervalTime;
tt= getTime(st);
} catch (java.text.ParseException e) {
e.printStackTrace();
}
return tt;
}
/**
* @param mis
* @return HH:mm:ss
*/
@SuppressLint("SimpleDateFormat")
public static String getTime(long mis){
SimpleDateFormat dff = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String ee = dff.format(new Date(mis));
return ee.substring(11);
}
上⾯的⽅法中, ts参数就是服务器返回的当前时间,形如yyyy-MM-dd hh:mm:ss的字符串intervalTime参数,是获取到服务器响应到⽤户进⾏操作的时间间隔,就是使⽤上⾯的elapsedRealtime ()⽅法获取两次时间计算得到。

⽅法的返回值String,形如 HH:mm:ss,这样返回字符串⽅便⽐较时间字符。

由于视频事件限制,就是时分秒,不可能涉及到年⽉⽇,所以这⾥就是直接返回时分秒。

有了这个⽅法,完美解决了android APP与服务器时间保持基本⼀致的需求。

但是还是存在⼀定的问题的,因为服务器返回时间不定,可能长可能短,所以时间并不会和服务器的当前时间分秒不差,总会有延时,但是这个延时可以接受,⼤概最多在10秒左右。

可以在时间间隔上稍微加⼀点就可以了。

基本就满⾜需求了。

以上就是本⽂的全部内容,希望对⼤家的学习有所帮助,也希望⼤家多多⽀持。

相关文档
最新文档