关于计算机恢复到几小时钱Java的补课,大概多少钱一个小时

【话题】关于非计算机专业出身,能做好Java吗?8 months ago9收藏分享举报{&debug&:false,&apiRoot&:&&,&paySDK&:&https:\u002F\u002Fpay.zhihu.com\u002Fapi\u002Fjs&,&wechatConfigAPI&:&\u002Fapi\u002Fwechat\u002Fjssdkconfig&,&name&:&production&,&instance&:&column&,&tokens&:{&X-XSRF-TOKEN&:null,&X-UDID&:null,&Authorization&:&oauth c3cef7c66aa9e6a1e3160e20&}}{&database&:{&Post&:{&&:{&isPending&:false,&contributes&:[],&title&:&【话题】关于非计算机专业出身,能做好Java吗?&,&author&:&javada-shi&,&content&:&\u003Cp\u003E\u003Cb\u003E快速学习,多阅读,多实践\u003C\u002Fb\u003E”\u003C\u002Fp\u003E\u003Cp\u003EIT行业与其它行业相比,它的技术变更更加快速,可能每天都会有新的技术出现,你每天也都会接受到新的名词、新的技术、新的架构体系。\u003Cb\u003E身处在这个变化如此之快的行业,快速学习的能力变得非常重要。\u003C\u002Fb\u003E比如一个新技术出来,你的老板可能需要你用一个月的时间用这个新技术完成一个项目,一般这种情况下,你最多只有一周时间完成对这个技术基本入门,后面就是一边用一边学。\u003C\u002Fp\u003E\u003Cp\u003E说到学习能力,我需要特别强调一点的是\u003Cb\u003E英文的阅读能力\u003C\u002Fb\u003E。其实作为程序猿,英语能力是不可或缺的。毕竟计算机这整套体系都是老外创造出来的,所以我们在学习新技术的时候面对的大部分都是英文文档。这个时候,就特别需要我们有一个良好的英语阅读的能力,这样我们才能更好的快速掌握相关的技术信息。\u003C\u002Fp\u003E\u003Cp\u003E学习新技能的时候,\u003Cb\u003E除了阅读文档,另外我们需要做的就是多动手实践,多写代码。\u003C\u002Fb\u003E很多学员在交流的时候都会跟我反应一个问题,就是说跟着老师的视频会写代码,但是自己写就写不出来。其实写代码也是一个熟能生巧的事情,代码敲的多了自然而然的就会写了,如果写不出来说明代码还写得不够多。反复练习,积累达到一定的量就会有一些写代码的灵感,进而就会产生一种质变。总而言之就是,纸上得来终觉浅,绝知此事要躬行。\u003C\u002Fp\u003E\u003Cp\u003E\u003Cb\u003E注重基础,抓住核心\u003C\u002Fb\u003E\u003C\u002Fp\u003E\u003Cp\u003E”前面提到IT领域技术更新很快,我们需要有一个快速学习的能力。对于一个初学者来说,面对纷繁复杂的各种技术,很多人都会一时手足无措,不知道从哪里下手,很多跨专业的同学都会遇到这个问题。我这边需要说的是,\u003Cb\u003E虽然这个领域技术繁多,新的技术也都层出不穷,但是有一句古话,万变不离其宗,这句话就是强调我们需要去抓住所谓的那个宗,也就是我们所指的技术的基础与核心。\u003C\u002Fb\u003E\u003C\u002Fp\u003E\u003Cp\u003E作为非计算机专业的同学,我不建议大家一开始就去学习Java或者C语言,还有所谓的各种框架。很多非计算机专业的同学可能会通过自学或者社会上的一些所谓的快速培训机构学习编程,在短暂的学习后就能够自己做出一两个简单的项目,甚至能够胜任普通工作中的一般任务。\u003Cb\u003E但是由于没有对计算机专业知识进行系统性的学习,对计算机基础知识缺乏了解,所以在遇到一些涉及到计算机底层的一些东西的时候就会不知所措。\u003C\u002Fb\u003E比如计算机网络通信、数据库的设计规范、数据结构的优化、多进程多线程编程等等,这些都是非计算机专业的同学欠缺的知识。就好像盖房子,在没有打牢固地基的情况下就开始添砖加瓦,最后轰然倒塌是必然的。\u003C\u002Fp\u003E\u003Cp\u003E作为跨专业的同学,建议大家先学习一些计算机相关的知识,这里推荐一些书单。如果大家能把这几本书都能够完整的自学一遍,我想也就可以算是计算机入门了。\u003C\u002Fp\u003E\u003Cp\u003E\u003Cb\u003E《计算机体系机构》\u003C\u002Fb\u003E\u003C\u002Fp\u003E\u003Cp\u003E了解最基础的计算机硬件知识\u003C\u002Fp\u003E\u003Cp\u003E\u003Cb\u003E《计算机操作系统》\u003C\u002Fb\u003E\u003C\u002Fp\u003E\u003Cp\u003E了解整个操作系统的实现和编程环境\u003C\u002Fp\u003E\u003Cp\u003E\u003Cb\u003E《编译原理》《计算机网络》\u003C\u002Fb\u003E\u003C\u002Fp\u003E\u003Cp\u003E了解编程语言的原理和网络原理\u003C\u002Fp\u003E\u003Cp\u003E\u003Cb\u003E《数据结构与算法》\u003C\u002Fb\u003E\u003C\u002Fp\u003E\u003Cp\u003E了解编程中常用的数据结构与经典算法\u003C\u002Fp\u003E\u003Cp\u003E这里打个比喻,如果大家先将计算机专业的知识体系建立起来了,就好像先练就了一身九阳神功,后面再学任务其它武功就是易如反掌,这样才有可能做到我之前提到的快速学习。\u003C\u002Fp\u003E\u003Cp\u003E\u003Cb\u003E勤写技术博客,与牛人多交流\u003C\u002Fb\u003E\u003C\u002Fp\u003E\u003Cp\u003E”写技术博客是一种可以快速提高的方法,我们可以分享自己总结的一些经验,也可以分享自己的体会。\u003Cb\u003E一样东西在你大脑里,并不代表你已经掌握了,如果你能说给别人听,或者用文字表达出来,那才算真正掌握了。\u003C\u002Fb\u003E\u003C\u002Fp\u003E\u003Cp\u003E大家在刚刚写技术博客的时候不要担心自己分享的东西太low,只要你认为是有价值,都可以写出来,这不仅可以给别人提供知识,同时也能够整理自己的思路,有时候还可以得到网上朋友的意见和反馈,跟大家一起交流。\u003C\u002Fp\u003E\u003Cp\u003E在IT这个领域,你会发现周围有很多技术牛人,他们都身怀绝杀武功,通常他们都很低调,低调到你都很难发现。如果你发现周围或者网上有这样的同事或者朋友,就可以多跟他做一些技术交流和讨论,在这个交流和讨论的过程中你会学习到他思考问题的思路和方法,同时也会加深对知识的理解,这样也是一种快速提高很好的方法。\u003C\u002Fp\u003E\u003Cp\u003E\u003Cb\u003E主动寻找项目经验\u003C\u002Fb\u003E\u003C\u002Fp\u003E\u003Cp\u003E”最后当我们内功都已经练好准备要出去面试的时候,经常会被问到项目经验的问题。因为作为一个成熟的企业,它肯定希望招到的人能够快速为公司产生价值,这里不管是对于校招或者社招都是一样。但是对于大多数跨专业的同学,这就是非常大的难题。这里给大家支两招:\u003C\u002Fp\u003E\u003Cp\u003E\u003Cb\u003E| 开源项目\u003C\u002Fb\u003E\u003C\u002Fp\u003E\u003Cp\u003E最简单直接获取项目经验的方法就是参与到开源项目的开发中,我们可以先到开源中国或者github上找一些不是那么复杂的开源项目开始练手,当然如果你自己有创意,可以自己建立一个开源项目,动手实践。\u003C\u002Fp\u003E\u003Cp\u003E\u003Cb\u003E| 无偿工作\u003C\u002Fb\u003E\u003C\u002Fp\u003E\u003Cp\u003E有时候可能开源项目的需求不是那么明确,跟实际的项目还是有一定差距;那我想说的是大家可以去找一些无偿工作的机会,普通的企业通常可能并不想雇佣经验少或没有经验的人,但是非盈利的机构通常会愿意雇佣这样的人;只要有合适的项目,最后能够获得项目经验,锻炼自己成长,有没有报酬都是无所谓的。\u003C\u002Fp\u003E\u003Cp\u003E世上无难事只怕有心人。我想对于非计算机专业的同学,只要能够按照一定的方法坚持学习,动手实践,时刻保持对知识的追求和渴望,有朝一日一定可以成为这个行业的佼佼者。\u003C\u002Fp\u003E\u003Cp\u003E就像上文所说的那样,Java学习的道路上除了自学外,另一个好方法就是找牛人交流,借助他人的经历获取高效的学习方法和快速进阶的方式。\u003C\u002Fp\u003E\u003Cbr\u003E\u003Cp\u003E最后,欢迎大家下面评论交流!\u003C\u002Fp\u003E&,&updated&:new Date(&T01:37:40.000Z&),&canComment&:false,&commentPermission&:&anyone&,&commentCount&:4,&collapsedCount&:0,&likeCount&:9,&state&:&published&,&isLiked&:false,&slug&:&&,&isTitleImageFullScreen&:false,&rating&:&none&,&titleImage&:&https:\u002F\u002Fpic1.zhimg.com\u002Fv2-e413c9b9e195d4c96dd5f_r.jpg&,&links&:{&comments&:&\u002Fapi\u002Fposts\u002F2Fcomments&},&reviewers&:[],&topics&:[{&url&:&https:\u002F\u002Fwww.zhihu.com\u002Ftopic\u002F&,&id&:&&,&name&:&Java&},{&url&:&https:\u002F\u002Fwww.zhihu.com\u002Ftopic\u002F&,&id&:&&,&name&:&Java 编程&},{&url&:&https:\u002F\u002Fwww.zhihu.com\u002Ftopic\u002F&,&id&:&&,&name&:&Java EE&}],&adminClosedComment&:false,&titleImageSize&:{&width&:500,&height&:268},&href&:&\u002Fapi\u002Fposts\u002F&,&excerptTitle&:&&,&tipjarState&:&closed&,&annotationAction&:[],&sourceUrl&:&&,&pageCommentsCount&:4,&hasPublishingDraft&:false,&snapshotUrl&:&&,&publishedTime&:&T09:37:40+08:00&,&url&:&\u002Fp\u002F&,&lastestLikers&:[{&bio&:&IT&,&isFollowing&:false,&hash&:&631c63caca559c11cfdab7&,&uid&:320400,&isOrg&:false,&slug&:&liu-zhen-30-35&,&isFollowed&:false,&description&:&&,&name&:&刘震&,&profileUrl&:&https:\u002F\u002Fwww.zhihu.com\u002Fpeople\u002Fliu-zhen-30-35&,&avatar&:{&id&:&da8e974dc&,&template&:&https:\u002F\u002Fpic4.zhimg.com\u002F{id}_{size}.jpg&},&isOrgWhiteList&:false,&isBanned&:false},{&bio&:&java程序员&,&isFollowing&:false,&hash&:&2faa5ae73ca37c21b8346f7&,&uid&:987100,&isOrg&:false,&slug&:&wang-fei-74-33&,&isFollowed&:false,&description&:&&,&name&:&王飞&,&profileUrl&:&https:\u002F\u002Fwww.zhihu.com\u002Fpeople\u002Fwang-fei-74-33&,&avatar&:{&id&:&dd6230adbc&,&template&:&https:\u002F\u002Fpic1.zhimg.com\u002F{id}_{size}.jpg&},&isOrgWhiteList&:false,&isBanned&:false},{&bio&:&&,&isFollowing&:false,&hash&:&193a0cdb78cec84e26fe02468caf13fb&,&uid&:443700,&isOrg&:false,&slug&:&ooo-87-64&,&isFollowed&:false,&description&:&&,&name&:&OOO&,&profileUrl&:&https:\u002F\u002Fwww.zhihu.com\u002Fpeople\u002Fooo-87-64&,&avatar&:{&id&:&v2-f58799feedec389a83629&,&template&:&https:\u002F\u002Fpic1.zhimg.com\u002F{id}_{size}.jpg&},&isOrgWhiteList&:false,&isBanned&:false},{&bio&:&HelloWorld&,&isFollowing&:false,&hash&:&fdf400f63f636dc2172b&,&uid&:465300,&isOrg&:false,&slug&:&chen-kai-21-15&,&isFollowed&:false,&description&:&&,&name&:&陈凯&,&profileUrl&:&https:\u002F\u002Fwww.zhihu.com\u002Fpeople\u002Fchen-kai-21-15&,&avatar&:{&id&:&v2-59ff89f14ac1d4e0b28b7&,&template&:&https:\u002F\u002Fpic1.zhimg.com\u002F{id}_{size}.jpg&},&isOrgWhiteList&:false,&isBanned&:false},{&bio&:&码幼\u002FJava渣渣&,&isFollowing&:false,&hash&:&1ec30afa27f7a96f829d5&,&uid&:066200,&isOrg&:false,&slug&:&miochan&,&isFollowed&:false,&description&:&年轻的老人&,&name&:&澪orz&,&profileUrl&:&https:\u002F\u002Fwww.zhihu.com\u002Fpeople\u002Fmiochan&,&avatar&:{&id&:&d1fb2c8df6b242dcf1d7&,&template&:&https:\u002F\u002Fpic2.zhimg.com\u002F{id}_{size}.jpg&},&isOrgWhiteList&:false,&isBanned&:false}],&summary&:&\u003Cb\u003E快速学习,多阅读,多实践\u003C\u002Fb\u003E”IT行业与其它行业相比,它的技术变更更加快速,可能每天都会有新的技术出现,你每天也都会接受到新的名词、新的技术、新的架构体系。\u003Cb\u003E身处在这个变化如此之快的行业,快速学习的能力变得非常重要。\u003C\u002Fb\u003E比如一个新技术出来,你的老板可…&,&reviewingCommentsCount&:0,&meta&:{&previous&:null,&next&:null},&annotationDetail&:null,&commentsCount&:4,&likesCount&:9,&FULLINFO&:true}},&User&:{&javada-shi&:{&isFollowed&:false,&name&:&Java&,&headline&:&java学习交流群: ,提供最专业的java免费学习公开课分享!&,&avatarUrl&:&https:\u002F\u002Fpic2.zhimg.com\u002Fv2-f56aca1c0408547bdb9b81_s.jpg&,&isFollowing&:false,&type&:&people&,&slug&:&javada-shi&,&bio&:&java Android 软件开发 目前一名5年的java开发者&,&hash&:&b7efd7a0035a8&,&uid&:697900,&isOrg&:false,&description&:&java学习交流群: ,提供最专业的java免费学习公开课分享!&,&badge&:{&identity&:null,&bestAnswerer&:null},&profileUrl&:&https:\u002F\u002Fwww.zhihu.com\u002Fpeople\u002Fjavada-shi&,&avatar&:{&id&:&v2-f56aca1c0408547bdb9b81&,&template&:&https:\u002F\u002Fpic2.zhimg.com\u002F{id}_{size}.jpg&},&isOrgWhiteList&:false,&isBanned&:false}},&Comment&:{},&favlists&:{}},&me&:{},&global&:{&experimentFeatures&:{&ge3&:&ge3_9&,&ge2&:&ge2_1&,&navi&:&1&,&growthSearch&:&s2&,&nwebQAGrowth&:&experiment&,&qawebRelatedReadingsContentControl&:&close&,&liveStore&:&ls_a2_b2_c1_f2&,&nwebSearch&:&nweb_search_heifetz&,&vdlc&:&e&,&rt&:&y&,&isOffice&:&false&,&enableTtsPlay&:&post&,&newLiveFeedMediacard&:&new&,&newMobileAppHeader&:&true&,&androidPassThroughPush&:&all&,&hybridZhmoreVideo&:&yes&,&nwebGrowthPeople&:&default&,&nwebSearchSuggest&:&default&,&qrcodeLogin&:&qrcode&,&enableVoteDownReasonMenu&:&enable&,&play&:&0&,&isShowUnicomFreeEntry&:&unicom_free_entry_off&,&growthBanner&:&default&,&newMobileColumnAppheader&:&new_header&,&androidDbRecommendAction&:&open&,&biu&:&1&,&info&:&1&,&androidDbFeedHashTagStyle&:&button&,&appStoreRateDialog&:&close&,&default&:&None&,&isNewNotiPanel&:&no&,&biua&:&1&,&zcmLighting&:&zcm&,&adR&:&b&,&wechatShareModal&:&wechat_share_modal_show&,&uRe&:&0&,&androidProfilePanel&:&panel_b&}},&columns&:{&next&:{}},&columnPosts&:{},&columnSettings&:{&colomnAuthor&:[],&uploadAvatarDetails&:&&,&contributeRequests&:[],&contributeRequestsTotalCount&:0,&inviteAuthor&:&&},&postComments&:{},&postReviewComments&:{&comments&:[],&newComments&:[],&hasMore&:true},&favlistsByUser&:{},&favlistRelations&:{},&promotions&:{},&switches&:{&couldSetPoster&:false},&draft&:{&titleImage&:&&,&titleImageSize&:{},&isTitleImageFullScreen&:false,&canTitleImageFullScreen&:false,&title&:&&,&titleImageUploading&:false,&error&:&&,&content&:&&,&draftLoading&:false,&updating&:false,&globalLoading&:false,&pendingVideo&:{&resource&:null,&error&:null}},&drafts&:{&draftsList&:[],&next&:{}},&config&:{&userNotBindPhoneTipString&:{}},&recommendPosts&:{&articleRecommendations&:[],&columnRecommendations&:[]},&env&:{&edition&:{&baidu&:false,&yidianzixun&:false,&qqnews&:false},&isAppView&:false,&appViewConfig&:{&content_padding_top&:128,&content_padding_bottom&:56,&content_padding_left&:16,&content_padding_right&:16,&title_font_size&:22,&body_font_size&:16,&is_dark_theme&:false,&can_auto_load_image&:true,&app_info&:&OS=iOS&},&isApp&:false,&userAgent&:{&ua&:&Mozilla\u002F5.0 (compatible, MSIE 11, Windows NT 6.3; Trident\u002F7.0; rv:11.0) like Gecko&,&browser&:{&name&:&IE&,&version&:&11&,&major&:&11&},&engine&:{&version&:&7.0&,&name&:&Trident&},&os&:{&name&:&Windows&,&version&:&8.1&},&device&:{},&cpu&:{}}},&message&:{&newCount&:0},&pushNotification&:{&newCount&:0}}87被浏览13,783分享邀请回答155 条评论分享收藏感谢收起codeforces.com/submissions/Petr。&附上神图镇楼&4.论据四
人所皆知BigInteger,BigDecimal,记得曾经跟cxlove和芒果打浙江省赛的时候Java用的不熟,只能用Java打表用C++提交,别提多蛋疼了。。综上,用好Java直接走天下。没必要一定去学C++只不过在打某算法比赛的时候要注意一下,比如读入加速啊,一些类的构成啊,具体就看一下Egor大爷的Code吧————————————————————————————————————————我是弱菜,说错了请大家包涵。 7912 条评论分享收藏感谢收起本系列文章经补充和完善,已修订整理成书《Java编程的逻辑》,由机械工业出版社华章分社出版,于2018年1月上市热销,读者好评如潮!各大网店和书店有售,欢迎购买,京东自营链接:
本节和下节,我们讨论在Java中如何进行日期和时间相关的操作。
日期和时间是一个比较复杂的概念,Java API中对它的支持不是特别好,有一个第三方的类库反而特别受欢迎,这个类库是Joda-Time,Java 1.8受Joda-Time影响,重新设计了日期和时间API,新增了一个包java.time。
虽然之前的设计有一些不足,但Java API依然是被大量使用的,本节介绍Java 1.8之前API中对日期和时间的支持,下节介绍Joda-Time,Java 1.8中的新API与Joda-Time比较类似,暂时就不介绍了。
关于日期和时间,有一些基本概念,我们先来看下。
我们都知道,同一时刻,世界上各个地区的时间可能是不一样的,具体时间与时区有关,一共有24个时区,英国格林尼治是0时区,北京是东八区,也就是说格林尼治凌晨1点,北京是早上9点。0时区的时间也称为GMT+0时间,GMT是格林尼治标准时间,北京的时间就是GMT+8:00。
时刻和Epoch Time (纪元时)
所有计算机系统内部都用一个整数表示时刻,这个整数是距离格林尼治标准时间日0时0分0秒的毫秒数。为什么要用这个时间呢?更多的是历史原因,本文就不介绍了。
格林尼治标准时间日0时0分0秒也被称为Epoch Time (纪元时)。
这个整数表示的是一个时刻,与时区无关,世界上各个地方都是同一个时刻,但各个地区对这个时刻的解读,如年月日时分秒,可能是不一样的。
如何表示1970年以前的时间呢?使用负数。
我们都知道,中国有公历和农历之分,公历和农历都是年历,不同的年历,一年有多少月,每月有多少天,甚至一天有多少小时,这些可能都是不一样的。
比如,公历有闰年,闰年2月是29天,而其他年份则是28天,其他月份,有的是30天,有的是31天。农历有闰月,比如闰7月,一年就会有两个7月,一共13个月。
公历是世界上广泛采用的年历,除了公历,还有其他一些年历,比如日本也有自己的年历。Java API的设计思想是支持国际化的,支持多种年历,但实际中没有直接支持中国的农历,本文主要讨论公历。
简单总结下,时刻是一个绝对时间,对时刻的解读,如年月日周时分秒等,则是相对的,与年历和时区相关。
Java日期和时间API
Java API中关于日期和时间,有三个主要的类:
Date:表示时刻,即绝对时间,与年月日无关。
Calendar:表示年历,Calendar是一个抽象类,其中表示公历的子类是GregorianCalendar
DateFormat:表示格式化,能够将日期和时间与字符串进行相互转换,DateFormat也是一个抽象类,其中最常用的子类是SimpleDateFormat。&
还有两个相关的类:
TimeZone: 表示时区
Locale: 表示国家和语言&
下面,我们来看这些类。
Date是Java API中最早引入的关于日期的类,一开始,Date也承载了关于年历的角色,但由于不能支持国际化,其中的很多方法都已经过时了,被标记为了@Deprecated,不再建议使用。
Date表示时刻,内部主要是一个long类型的值,如下所示:
private transient long fastT
fastTime表示距离纪元时的毫秒数,此处,关于transient关键字,我们暂时忽略。
Date有两个构造方法:
public Date(long date) {
fastTime =
public Date() {
this(System.currentTimeMillis());
第一个构造方法,就是根据传入的毫秒数进行初始化,第二个构造方法是默认构造方法,它根据System.currentTimeMillis()的返回值进行初始化。System.currentTimeMillis()是一个常用的方法,它返回当前时刻距离纪元时的毫秒数。
Date中的大部分方法都已经过时了,其中没有过时的主要方法有:
返回毫秒数
public long getTime()
判断与其他Date是否相同
public boolean equals(Object obj)
主要就是比较内部的毫秒数是否相同。
与其他Date进行比较
public int compareTo(Date anotherDate)
Date实现了Comparable接口,比较也是比较内部的毫秒数,如果当前Date的毫秒数小于参数中的,返回-1,相同返回0,否则返回1。
除了compareTo,还有另外两个方法,与给定日期比较,判断是否在给定日期之前或之后,内部比较的也是毫秒数。
public boolean before(Date when)
public boolean after(Date when)
public int hashCode()
哈希值算法与Long类似。
TimeZone表示时区,它是一个抽象类,有静态方法用于获取其实例。
获取当前的默认时区,代码为:
TimeZone tz = TimeZone.getDefault();
System.out.println(tz.getID());
获取默认时区,并输出其ID,在我的电脑上,输出为:
Asia/Shanghai
默认时区是在哪里设置的呢,可以更改吗?Java中有一个系统属性,user.timezone,保存的就是默认时区,系统属性可以通过System.getProperty获得,如下所示:
System.out.println(System.getProperty("user.timezone"));
在我的电脑上,输出为:
Asia/Shanghai
系统属性可以在Java启动的时候传入参数进行更改,如
java -Duser.timezone=Asia/Shanghai xxxx
TimeZone也有静态方法,可以获得任意给定时区的实例,比如:
获取美国东部时区
TimeZone tz = TimeZone.getTimeZone("US/Eastern");
ID除了可以是名称外,还可以是GMT形式表示的时区,如:
TimeZone tz = TimeZone.getTimeZone("GMT+08:00");
国家和语言Locale
Locale表示国家和语言,它有两个主要参数,一个是国家,另一个是语言,每个参数都有一个代码,不过国家并不是必须的。
比如说,中国的大陆代码是CN,台湾地区的代码是TW,美国的代码是US,中文语言的代码是zh,英文是en。
Locale类中定义了一些静态变量,表示常见的Locale,比如:
Locale.US:表示美国英语
Locale.ENGLISH:表示所有英语
Locale.TAIWAN:表示台湾中文
Locale.CHINESE:表示所有中文
Locale.SIMPLIFIED_CHINESE:表示大陆中文
与TimeZone类似,Locale也有静态方法获取默认值,如:
Locale locale = Locale.getDefault();
System.out.println(locale.toString());
在我的电脑上,输出为:
Calendar类是日期和时间操作中的主要类,它表示与TimeZone和Locale相关的日历信息,可以进行各种相关的运算。
我们先来看下它的内部组成。
与Date类似,Calendar内部也有一个表示时刻的毫秒数,定义为:
protected long
除此之外,Calendar内部还有一个数组,表示日历中各个字段的值,定义为:
protected int
这个数组的长度为17,保存一个日期中各个字段的值,都有哪些字段呢?Calendar类中定义了一些静态变量,表示这些字段,主要有:
Calendar.YEAR:表示年
Calendar.MONTH:表示月,一月份是0,Calendar同样定义了表示各个月份的静态变量,如Calendar.JULY表示7月。
Calendar.DAY_OF_MONTH:表示日,每月的第一天是1。
Calendar.HOUR_OF_DAY:表示小时,从0到23。
Calendar.MINUTE:表示分钟,0到59。
Calendar.SECOND:表示秒,0到59。
Calendar.MILLISECOND:表示毫秒,0到999。
Calendar.DAY_OF_WEEK:表示星期几,周日是1,周一是2,周六是7,Calenar同样定义了表示各个星期的静态变量,如Calendar.SUNDAY表示周日。&
获取Calendar实例
Calendar是抽象类,不能直接创建对象,它提供了四个静态方法,可以获取Calendar实例,分别为:
public static Calendar getInstance()
public static Calendar getInstance(Locale aLocale)
public static Calendar getInstance(TimeZone zone)
public static Calendar getInstance(TimeZone zone, Locale aLocale)
最终调用的方法都是需要TimeZone和Locale的,如果没有,则会使用上面介绍的默认值。getInstance方法会根据TimeZone和Locale创建对应的Calendar子类对象,在中文系统中,子类一般是表示公历的GregorianCalendar。
getInstance方法封装了Calendar对象创建的细节,TimeZone和Locale不同,具体的子类可能不同,但都是Calendar,这种隐藏对象创建细节的方式,是计算机程序中一种常见的设计模式,它有一个名字,叫工厂方法,getInstance就是一个工厂方法,它生产对象。
获取日历信息
与new Date()类似,新创建的Calendar对象表示的也是当前时间,与Date不同的是,Calendar对象可以方便的获取年月日等日历信息。
来看代码,输出当前时间的各种信息:
Calendar calendar = Calendar.getInstance();
System.out.println("year: "+calendar.get(Calendar.YEAR));
System.out.println("month: "+calendar.get(Calendar.MONTH));
System.out.println("day: "+calendar.get(Calendar.DAY_OF_MONTH));
System.out.println("hour: "+calendar.get(Calendar.HOUR_OF_DAY));
System.out.println("minute: "+calendar.get(Calendar.MINUTE));
System.out.println("second: "+calendar.get(Calendar.SECOND));
System.out.println("millisecond: " +calendar.get(Calendar.MILLISECOND));
System.out.println("day_of_week: " + calendar.get(Calendar.DAY_OF_WEEK));
具体输出与执行时的时间和默认的TimeZone以及Locale有关,在写作时,我的电脑上的输出为:
year: 2016
minute: 55
second: 51
millisecond: 564
day_of_week: 2
内部,Calendar会将表示时刻的毫秒数,按照TimeZone和Locale对应的年历,计算各个日历字段的值,存放在fields数组中,Calendar.get方法获取的就是fields数组中对应字段的值。
设置和修改时间
Calendar支持根据Date或毫秒数设置时间:
public final void setTime(Date date)
public void setTimeInMillis(long millis)
也支持根据年月日等日历字段设置时间:
public final void set(int year, int month, int date)
public final void set(int year, int month, int date, int hourOfDay, int minute)
public final void set(int year, int month, int date, int hourOfDay, int minute, int second)
public void set(int field, int value)
除了直接设置,Calendar支持根据字段增加和减少时间:
public void add(int field, int amount)
amount为正数表示增加,负数表示减少。
比如说,如果想设置Calendar为第二天的下午2点15,代码可以为:
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.DAY_OF_MONTH, 1);
calendar.set(Calendar.HOUR_OF_DAY, 14);
calendar.set(Calendar.MINUTE, 15);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
Calendar的这些方法中一个比较方便和强大的地方在于,它能够自动调整相关的字段。
比如说,我们知道二月份最多有29天,如果当前时间为1月30号,对Calendar.MONTH字段加1,即增加一月,Calendar不是简单的只对月字段加1,那样日期是2月30号,是无效的,Calendar会自动调整为2月最后一天,即2月28或29。
再比如,设置的值可以超出其字段最大范围,Calendar会自动更新其他字段,如:
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.HOUR_OF_DAY, 48);
calendar.add(Calendar.MINUTE, -120);
相当于增加了46小时。
内部,根据字段设置或修改时间时,Calendar会更新fields数组对应字段的值,但一般不会立即更新其他相关字段或内部的毫秒数的值,不过在获取时间或字段值的时候,Calendar会重新计算并更新相关字段。
简单总结下,Calenar做了一项非常繁琐的工作,根据TimeZone和Locale,在绝对时间毫秒数和日历字段之间自动进行转换,且对不同日历字段的修改进行自动同步更新。
除了add,Calendar还有一个类似的方法:
public void roll(int field, int amount)
与add的区别是,这个方法不影响时间范围更大的字段值。比如说:
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, 13);
calendar.set(Calendar.MINUTE, 59);
calendar.add(Calendar.MINUTE, 3);
calendar首先设置为13:59,然后分钟字段加3,执行后的calendar时间为14:02。如果add改为roll,即:
calendar.roll(Calendar.MINUTE, 3);
则执行后的calendar时间会变为13:02,在分钟字段上执行roll不会改变小时的值。
转换为Date或毫秒数
Calendar可以方便的转换为Date或毫秒数,方法是:
public final Date getTime()
public long getTimeInMillis()
Calendar的比较
与Date类似,Calendar之间也可以进行比较,也实现了Comparable接口,相关方法有:
public boolean equals(Object obj)
public int compareTo(Calendar anotherCalendar)
public boolean after(Object when)
public boolean before(Object when)
DateFormat
DateFormat类主要在Date和字符串表示之间进行相互转换,它有两个主要的方法:
public final String format(Date date)
public Date parse(String source)
format将Date转换为字符串,parse将字符串转换为Date。
Date的字符串表示与TimeZone和Locale都是相关的,除此之外,还与两个格式化风格有关,一个是日期的格式化风格,另一个是时间的格式化风格。
DateFormat定义了四个静态变量,表示四种风格,SHORT、MEDIUM、LONG和FULL,还定义了一个静态变量DEFAULT,表示默认风格,值为MEDIUM,不同风格输出的信息详细程度不同。
与Calendar类似,DateFormat也是抽象类,也用工厂模式创建对象,提供了多个静态方法创建DateFormat对象,有三类方法:
public final static DateFormat getDateTimeInstance()
public final static DateFormat getDateInstance()
public final static DateFormat getTimeInstance()
getDateTimeInstance既处理日期也处理时间,getDateInstance只处理日期,getTimeInstance只处理时间,看下面代码:
Calendar calendar = Calendar.getInstance();
// 14:15:20
calendar.set(, 14, 15, 20);
System.out.println(DateFormat.getDateTimeInstance()
.format(calendar.getTime()));
System.out.println(DateFormat.getDateInstance()
.format(calendar.getTime()));
System.out.println(DateFormat.getTimeInstance()
.format(calendar.getTime()));
每类工厂方法都有两个重载的方法,接受日期和时间风格以及Locale作为参数:
DateFormat getDateTimeInstance(int dateStyle, int timeStyle)
DateFormat getDateTimeInstance(int dateStyle, int timeStyle, Locale aLocale)
比如,看下面代码:
Calendar calendar = Calendar.getInstance();
// 14:15:20
calendar.set(, 14, 15, 20);
System.out.println(DateFormat.getDateTimeInstance(
DateFormat.LONG,DateFormat.SHORT,Locale.CHINESE)
.format(calendar.getTime()));
日 下午2:15
DateFormat的工厂方法里,我们没看到TimeZone参数,不过,DateFormat提供了一个setter方法,可以设置TimeZone:
public void setTimeZone(TimeZone zone)
DateFormat虽然比较方便,但如果我们要对字符串格式有更精确的控制,应该使用SimpleDateFormat这个类。
SimpleDateFormat
SimpleDateFormat是DateFormat的子类,相比DateFormat,它的一个主要不同是,它可以接受一个自定义的模式(pattern)作为参数,这个模式规定了Date的字符串形式。先看个例子:
Calendar calendar = Calendar.getInstance();
// 14:15:20
calendar.set(, 14, 15, 20);
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 E HH时mm分ss秒");
System.out.println(sdf.format(calendar.getTime()));
日 星期一 14时15分20秒
SimpleDateFormat有个构造方法,可以接受一个pattern作为参数,这里pattern是:
yyyy年MM月dd日 E HH时mm分ss秒
pattern中的英文字符a-z和A-Z表示特殊含义,其他字符原样输出,这里:
yyyy:表示四位的年
MM:表示月,两位数表示
dd:表示日,两位数表示
HH:表示24小时制的小时数,两位数表示
mm:表示分钟,两位数表示
ss:表示秒,两位数表示
E:表示星期几&
这里需要特意提醒一下,hh也表示小时数,但表示的是12小时制的小时数,而a表示的是上午还是下午,看代码:
Calendar calendar = Calendar.getInstance();
// 14:15:20
calendar.set(, 14, 15, 20);
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd hh:mm:ss a");
System.out.println(sdf.format(calendar.getTime()));
02:15:20 下午
更多的特殊含义可以参看SimpleDateFormat的Java文档。如果想原样输出英文字符,可以用单引号括起来。
除了将Date转换为字符串,SimpleDateFormat也可以方便的将字符转化为Date,看代码:
String str = " 14:15:20.456";
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
Date date = sdf.parse(str);
SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy年M月d h:m:s.S a");
System.out.println(sdf2.format(date));
} catch (ParseException e) {
e.printStackTrace();
2:15:20.456 下午
代码将字符串解析为了一个Date对象,然后使用另外一个格式进行了输出,这里SSS表示三位的毫秒数。
需要注意的是,parse会抛出一个受检异常(checked exception),异常类型为ParseException,调用者必须进行处理。
至此,关于Java 1.8之前的日期和时间相关API的主要内容,我们就介绍的差不多了,这里我们想强调一下这些API的一些局限性。
Date中的过时方法
Date中的方法参数与常识不符合,过时方法标记容易被人忽略,产生误用。比如说,看如下代码:
Date date = new Date();
System.out.println(DateFormat.getDateInstance().format(date));
想当然的输出为,但其实输出为:
之所以产生这个输出,是因为,Date构造方法中的year表示的是与1900年的差,month是从0开始的。
Calendar操作比较啰嗦臃肿
Calendar API的设计不是很成功,一些简单的操作都需要多次方法调用,写很多代码,比较啰嗦臃肿。
另外,Calendar难以进行比较复杂的日期操作,比如,计算两个日期之间有多少个月,根据生日计算年龄,计算下个月的第一个周一等。
下一节,我们会介绍Joda-Time,相比Calendar,Joda-Time要简洁方便的多。
DateFormat的线程安全性
DateFormat/SimpleDateFormat不是线程安全的,关于线程概念,后续文章我们会详解,这里简单说明一下,多个线程同时使用一个DateFormat实例的时候,会有问题,因为DateFormat内部使用了一个Calendar实例对象,多线程同时调用的时候,这个Calendar实例的状态可能就会紊乱。
解决这个问题大概有以下方案:
每次使用DateFormat都新建一个对象
使用线程同步
使用ThreadLocal
使用Joda-Time,Joda-Time是线程安全的
后续文章我们再介绍线程同步和ThreadLocal。
本节介绍了Java中(1.8之前)的日期和时间相关API,Date表示时刻,与年月日无关,Calendar表示日历,与时区和Locale相关,可进行各种运算,是日期时间操作的主要类,DateFormat/SimpleDateFormat在Date和字符串之间进行相互转换。
这些API存在着一些不足,操作比较复杂,代码比较臃肿,还有线程安全的问题,实际中一个常用的第三方库是Joda-Time,下一节,让我们一起来看下。
----------------
未完待续,查看最新文章,敬请关注微信公众号&老马说编程&(扫描下方二维码),从入门到高级,深入浅出,老马和你一起探索Java编程及计算机技术的本质。用心写作,原创文章,保留所有版权。
阅读(...) 评论()}

我要回帖

更多关于 高中补课1小时多少钱 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信