1. Prefácio
Eu encontrei um problema no trabalho recentemente. Há uma tarefa cronometrada no back -end. Preciso usar o Java para julgar as férias estatutárias, férias de fim de semana, trabalho etc. todos os dias. De fato, é basicamente impossível julgar apenas os feriados estatutários da China através da lógica, porque os feriados no país podem ser diferentes a cada ano e são definidos artificialmente;
Portanto, você só pode confiar em outros meios, e os mais confiáveis que você pode pensar são os seguintes:
1. Interface de rede: Alguns provedores de serviços de dados o fornecerão, para a cobrança ou para o limite do número de vezes, etc. O efeito não é o ideal e a controlabilidade é ruim. Eu nunca tentei, como:
https://www.juhe.cn/docs/api/id/177/aid/601
ou
http://apistore.baidu.com/apiworks/servicetetail/1116.html
2. Analise as informações da página da web on -line e obtenha situações de férias: confie fortemente nas páginas da web do site analisado; portanto, ao selecionar um site, você deve encontrar um um pouco mais confiável;
3. De acordo com os regulamentos nacionais sobre férias estatutárias, entra no sistema todos os anos, se os clientes não têm medo de problemas. Ainda relativamente confiável;
Esta demonstração escolherá o segundo a ser implementado;
2. Use htmlunit para analisar as informações da página da web on -line para obter situações de férias
No começo, usei o JSUP para analisar as páginas da web, mas o efeito não era o ideal. Se a página da web foi gerada dinamicamente, encontrei vários problemas com o JSUP, então mudei para htmlunit. Em geral, o htmlunit ainda é muito poderoso, pode simular a operação do navegador e é conhecido como implementação de código aberto dos navegadores Java;
Primeiro, vá ao site oficial para baixar os pacotes de jar relevantes e ler os documentos relevantes:
http://htmlunit.sourceforge.net/
A página da web que estou analisando aqui é um calendário perpétuo de 3,6 milhões:
http://hao.360.cn/rili/
A interface do calendário é a seguinte:
O formato HTML analisado é o seguinte:
Etapas de implementação:
1. Carregue a página;
2. Loop para aguardar o carregamento da página (pode haver algumas páginas dinâmicas, geradas usando JavaScript);
3. Paresia o conteúdo HTML de acordo com o formato da página da web e extrai as principais informações e o armazena para o objeto encapsulado;
Observação:
1. A dificuldade está em determinar se deve tirar férias e o tipo de férias. Como a página original não indica o tipo de férias para cada dia, a lógica aqui precisa ser implementada por você mesmo. Consulte o código para obter detalhes;
2. A razão para uma variável estática mais recente de nome de nome é impedir as seguintes situações (a probabilidade dessa situação é extremamente baixa; PS: o método deve ser chamado uma vez por dia antes da variável entrar em vigor):
Implementação de código:
Defina uma classe de data chinesa:
pacote com.pichen.tools.getdate; importar java.util.date; public class Chinadate {/*** time gregoriano*/private Data SOLARDATE;/*** DIA LUNAR*/String privada lunar;/*** INSTRATION DIA FALSON; "Não Vacação";/*** Se é uma classe*/private booleano isWorkFlag = false; private boolean Issurday = false; private boolean iSSUNDAYNAYRAY = FALSE;/*** @RETURN O SOLARDATE*/Public Date () {) {Return Solard;}/*** @param SOLARD O SOLATO A Set Setting* solardato;}/*** @return the lunar*/public string getLunar () {retorna lunar;}/*** @param lunar o lunar para definir*/public void setLunar (string lunar) {thisluning.lunar = lunar;}/*** @return o solar*/public string getSolar () {Solar Solar; setSolar (String solar) {this.solar = solar;}/*** @return the isvacation*/public boolean isvacation () {return isvacation;}/*** @param isvacation the isvacation to Set*/public void (ISVACation) { férias férias*/public String getVacationName () {Return fériasName;}/*** @param férias nome o nome de férias para definir*/public void setvacationName (string fériasName) {férias frigorias @@sFlag;}/*** @returing the isworklag*/public boolean isworkflag () {{} set*/public void setWorkflag (boolean isworkflag) {this.isworkflag = isworkflag;}/*** @RETURN O ISSURDAY*/public boolean ISSURDAY () {retorno ISSURDAYDADAY;}/*** @param Issaturday O ISSURDAY ISSTOLA*/Public Void SettaRday (boolean; ISSUNGAY*/public boolean ISSUNDAYN () {return iSSUNDAY;}/*** @param issunday the issunday to Set*/public void Setsunday (boolean iSsunday) {this.issunday = ISSUNDAY;}} Analisa a página da web e chama a demonstração, imprime os detalhes deste mês e os detalhes do dia:
pacote com.pichen.tools.getdate; importar java.io.ioException; importar java.net.malformedurlexception; importar java.text.dateFormat; import java.text.parseexception; import java.text.simpledformat; import java.util.Texception; import.mportyList; import.text.text.simpledformat; import java.util.utilist; importar; java.util.list; importar com.gargoyLesoftware.htmlunit.failinghttpstatuscodeexception; importação com.gargoylesoftware.htmlunit.webclient; importação com.gargoylesoftware.htmlunit.html.domnodelist; com.gargoylesoftware.htmlunit.html.htmlelement; importar com.gargoylesoftware.htmlunit.html.htmlpage; public class main {private static strt vocationName = "" public String GetVocationName (domnodelist <HtMellement. ""; boolean pasttimeflag = false; dateFormat dateFormat = new SimpleDateFormat ("yyyy/mm/dd"); date paramdate = dateFormat.parse (date); if (new date (). i <htmlelements.size (); = htmlelements.get (i); string lidate = elementTmp.getAttribute ("date"); list <htmlelement> lunar = elementTmp.getElementsByAttribute ("span", "classe"), "lunart"); string lanartExt = lunar.get (0) .Astext (); se (lanart "); Dia do ano ";} else if (LANARTEXT.EQUALS (" Véspera de Ano Novo ") || LANARTEXT.EQUALS (" Festival da primavera ")) {voationName =" Spring Festival ";} else if (lanartExt.equals (" qingming ") {voationName =" Spring Festival "; Festival ";} else if (LANARTEXT.EQUALS (" Dragon Boat Festival ")) {VoationName =" Dragon Boat Festival ";} else if (LANARTEXT.EQUALS (" Mid-Autumn Festival ")) {VoationName =" Mid-Autumn Festival ";} else if (lAnText.Equals (" dia "dia" dia ") Dia ";} if (lidate.equals (date)) {hitflag = true;} if (elementTmp.getAttribute (" classe "). Fail (raramente), obtenha do mais recente nome de vocação (rst.equals ("" ")) {System.out.println (" Aviso: não obtenha o nome da vocação da página html. "); // Você pode julgar por alguma regra simples // a partir da mais recente vocation namersst = main.latestvocationname;} sen se (PASSTIMEFLAGL (PASSTIMAGL (PASSTIMEFLAGL) Main.latestvocationName = rst;} retornar rst;} list public <flinadate> getCurrentDateInfo () {webclient webclient = null; list <flinArtate> datelist = null; try {dateFormat DateFormat = new SimplateFormat ("yyyy/mm/dd") Webclient (); htmlpage página = webclient.getPage ("http://hao.360.cn/rili/"); // aguarda (int k = 0; k <60; k ++) {if (! Page.getElementbyby ("M-dates"). Astext (). segundos, esperando a página carregar ... às vezes, a página não pode ser recuperada, instável () //thread.sleep(8000); para (elemento htmlelement: htmlelements) {Chinadate Chinadate = new Chinadate (); List <HtmleLement> lunar = element.getElementsByAttribute ("span", "classe", "lunar"); list <htmlement> solar = elementElementElementsbyattttttttttttttttttttttttttttttttTtttItTttIll; "Solar"); Chinadate.setLunar (Lunar.get (0) .astext ()); Chinadate.SetSolar (solar.get (0) .astext ()); Chinadate.SetSolardate (DateFormat.Parse (element.getTribute (" data "))); if (element.getAttribute (" classe "). element.getAttribute ("date"))));} if (element.getAttribute ("classe"). indexof ("fim de semana")! =-1 && element.getAttribute ("classe") fim de semana ")! =-1) {Chinadate.SetSUNDAY (true);} if (element.getAttribute (" classe "). ) {Chinadate.setworkflag (true);} else {Chinadate.setworkflag (false);} Datelist.add (Chinadate);}} Catch (Exceção e) {e.printstacktrace (); System.out.println ("Obtenha data de http://hoo.360.cn.cn.cn.cn.cnnn (" obtenha data de http://hoo.36il.cn.cn.cn. Finalmente {webclient.close ();} retorna datelist;} public ChinAdate getTodayinfo () {list <fladate> datelist = this.getCurrentDateInfo (); dateFormat DateFormat = new SimpleDateFormat ("yyyyy/mm/dd"); dateList){if(dateFormat.format(date.getSolarDate()).equals(dateFormat.format(new Date()))){return date;}}return new ChinaDate();}public static void main(String[] args) throws FailingHttpStatusCodeException, MalformedURLException, IOException, InterruptedException {List<ChinaDate> DataList = new Main (). getCurrentDateInfo (); Chinadate Today = new Main (). getTodayInfo (); DateFormat DateFormat = new SimpleDateFormat ("Aaaaa/mm/dd"); System.out.println ("Detalhes deste mês:"); Datelist) {System.out.println (DateFormat.Format (DATE.GETSOLARDATE ()) + "" + date.getvacationName ());} System.out.println ("--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- "+Today.getLunar ()); System.out.println (" Calendário Gregoriano: "+Today.getSolar ()); System.out.println (" Nome do feriado: "+Today.getvacationName ()); System.out.println (" Sábado: "+TOD ay.iSTRay ()); "+Today.issuNay ()); System.out.println (" está de férias: "+Today.isvacation ()); System.out.println (" está trabalhando no dia: "+Today.isworkflag ()); System.out.println (" Férias mais recentes que ocorreram: "+main.latsvocaltname); Execute o programa e o resultado está correto: