0

Im trying some automated bots here and need get the last day of last month. While at first run of the bot on the current month its working fine but on the next month the date that I get from this code

Calendar cal = Calendar.getInstance();
cal.add(Calendar.MONTH, -1);
cal.set(Calendar.DAY_OF_MONTH, cal.getActualMaximum(Calendar.DAY_OF_MONTH));
dateformat2 = new SimpleDateFormat((cal.get(Calendar.MONTH)+1)+"/"+cal.get(Calendar.DAY_OF_MONTH)+"/yyyy");

is not right. Here's the full code on my current bot class.

typeimport java.awt.event.AdjustmentEvent;
import java.awt.event.AdjustmentListener;
import java.io.File;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.TimeUnit;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;




public class Teco_Bot extends Thread{
    WebDriver driver;
    GUI gui;
    String user[]= {"NorthVillage432","VPM1263"};
    String pass[]= {"user123","user123"};
    String accId[]= {"0","1"};
    SimpleDateFormat dateformat1,dateformatDay,dateformat2,dateformat3;
    Statement st;
    ResultSet rs;
    
    public Teco_Bot() {
        dateformat1 = new SimpleDateFormat("yyyy-MM-dd");
        dateformatDay = new SimpleDateFormat("dd");
        
        dateformat3 = new SimpleDateFormat("MM/dd/yyyy");
                Calendar cal = Calendar.getInstance();
            cal.add(Calendar.MONTH, -1);
            cal.set(Calendar.DAY_OF_MONTH, cal.getActualMaximum(Calendar.DAY_OF_MONTH));
            dateformat2 = new SimpleDateFormat((cal.get(Calendar.MONTH)+1)+"/"+cal.get(Calendar.DAY_OF_MONTH)+"/yyyy");
        gui = new GUI();
        
    }
    
    public void run() {
        
        String currentdate="";
        EmailNotification notif1;
        EmailNotification notif2;
        while(true) {
            try {
                Thread.sleep(2000);
            }catch(Exception ee) {ee.printStackTrace();}
            System.out.println("Waiting");
                    
            
            if((dateformatDay.format(new Date()).equalsIgnoreCase("05")||dateformatDay.format(new Date()).equalsIgnoreCase("15"))&&!currentdate.equalsIgnoreCase(dateformat1.format(new Date())))
            {
                 notif1 = new EmailNotification("junrybuenavista@yahoo.com",30,"Teco Bot");
                 notif1.start();
                 notif2 = new EmailNotification("michaelvinocur@htgrp.net",30,"Teco Bot");
                 notif2.start();
                setDataBaseConnection();
                        while(true) {
                            for(int i=0;i<user.length;i++) {
                                setBrowser();
                                gui.textAppend("Processing "+user[i]+"\n");
                                Login(user[i],pass[i]);
                                
                                currentdate = dateformat1.format(new Date());
                                try {
                                    st.execute("DELETE FROM `teco_data`");
                                }catch(Exception ee) {ee.printStackTrace();}
                                    
                                getData();
                                if(driver.findElements(By.xpath("//*[@id=\"selectionForm\"]/div[3]/div[2]/div[2]/ul/li[2]/a")).size() != 0) {
                                    driver.findElement(By.xpath("//*[@id=\"selectionForm\"]/div[3]/div[2]/div[2]/ul/li[2]/a")).click();
                                    System.out.println();   
                                    getData();
                                }
                                
                                
                                
                                driver.get("http://localhost/googleapi/teco-query.php?day="+dateformatDay.format(new Date())+"&acc="+accId[i]+"&date="+dateformat2.format(new Date())+"&date2="+dateformat3.format(new Date()));
                                System.out.println("http://localhost/googleapi/teco-query.php?day="+dateformatDay.format(new Date())+"&acc="+accId[i]+"&date="+dateformat2.format(new Date())+"&date2="+dateformat3.format(new Date()));
                                try {
                                    Thread.sleep(4000);
                                }catch(Exception ee) {ee.printStackTrace();}
                                driver.quit();
                                try {
                                    Thread.sleep(2000);
                                }catch(Exception ee) {ee.printStackTrace();}
                                gui.textAppend("Processing complete\n\n");
                                                                
                            }
                            try {
                                st.close();
                                rs.close();
                            }catch(Exception ee) {ee.printStackTrace();}
                            break;
                        }
                        notif1.setIsRunning(true);
                        notif2.setIsRunning(true);
                    }                                   
        }
    }
    public void getData() {
        try {
                
                WebElement table = driver.findElement(By.xpath("//*[@id=\"selectionForm\"]/div[2]/table"));
                List<WebElement> acc = table.findElements(By.xpath(".//tr/td[2]"));
                List<WebElement> add = table.findElements(By.xpath(".//tr/td[3]"));
                List<WebElement> amount_due = table.findElements(By.xpath(".//tr/td[4]"));
                List<WebElement> due_date = table.findElements(By.xpath(".//tr/td[5]"));
                
                for(int i=0;i<acc.size();i++) {             
                    System.out.print(acc.get(i).getText()+" ");
                    System.out.print(add.get(i).getText()+" ");
                    System.out.print(amount_due.get(i).getText()+" ");
                    System.out.println(due_date.get(i).getText()+" ");
                    st.execute("INSERT INTO teco_data (acc, address, amount_due, due_date)\r\n"
                            + "VALUES ('"+acc.get(i).getText()+"', '"+add.get(i).getText()+"', '"+amount_due.get(i).getText()+"', '"+due_date.get(i).getText()+"');");
                }
        }catch(Exception ee) {ee.printStackTrace();}        
    }
    public void setDataBaseConnection() {
        while(true) {
            System.out.println("Database connecting");
            gui.textAppend("Database connecting\n");
            try{  
                Thread.sleep(1500);
                Class.forName("com.mysql.jdbc.Driver");  
                Connection con=DriverManager.getConnection(  
                "jdbc:mysql://localhost:3306/teco_db","root","");   
                 st=con.createStatement();
                 break;
                
               }catch(Exception e){}
        }
    }
    public void setBrowser() {      
        System.setProperty("webdriver.chrome.driver", "C:\\Jars\\chromedriver.exe");        
        HashMap<String,Object> chromePrefs = new HashMap<String, Object>();
        chromePrefs.put("plugins.always_open_pdf_externally", true);
        chromePrefs.put("download.default_directory", "C:"+File.separator+"Square_download");
        chromePrefs.put("excludeSwitches", "enable-popup-blocking");    
        ChromeOptions options = new ChromeOptions();
        options.setExperimentalOption("prefs", chromePrefs);
        
        driver = new ChromeDriver(options);
        driver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);    
    }
    public void Login(String user,String pass) {

        gui.textAppend("Starting Login\n");
        driver.get("https://account.tecoenergy.com/");
        try {
            Thread.sleep(2000);
        }catch(Exception ee) {ee.printStackTrace();}
        driver.findElement(By.id("UserName")).sendKeys(user);
        driver.findElement(By.id("Credentials_Password")).sendKeys(pass);
        driver.findElement(By.id("login-submit")).click();
        gui.textAppend("Login complete\n");
        try {
            Thread.sleep(4000);
        }catch(Exception ee) {ee.printStackTrace();}
        
    }
    
    class GUI  
    {   JTextArea area;
    
         GUI(){  
                 area=new JTextArea();
                 area.setEditable(false);
                
                 
                 JScrollPane scrollableTextArea = new JScrollPane(area);
                   scrollableTextArea.getVerticalScrollBar().addAdjustmentListener(new AdjustmentListener() {  
                        public void adjustmentValueChanged(AdjustmentEvent e) {  
                            e.getAdjustable().setValue(e.getAdjustable().getMaximum());  
                        }
                    });
                 JFrame frame=new JFrame("Teco bot Running");
                 frame.add(scrollableTextArea);
                 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                 frame.setSize(500,300);
                 frame.setLocationRelativeTo(null);
                 frame.setVisible(true);
         }
         public void textAppend(String stringIn) {
             area.append(stringIn);
         }
         public void textClear() {
             area.setText("");
         }
    }
} 

I gladly appreciated if anyone can help me out here.

I must get the right result on the last day of the last month even if the current month will change to next month on my bot automation.

  • "I must get the right result on the last day of the last month even if the current month will change to next month on my bot automation." - I'm not sure I understand. Do you mean that if you start this bot on December 31st 23:59,999 and it runs pretty much into Jan 1st you still want to get Nov 30th as the "last day of last month"? If so, you should take that time right at the start and even then there's a chance the "bot" runs into Jan 1st before getting it. Is that kind of precision really needed? – Thomas Jan 12 '23 at 08:31
  • 3
    Also, using `Calendar` is already a sign of something going wrong. Have a look at the "new" `java.time` API that's been around for years now (since Java 8). That has pretty much every method you'd need, e.g. `LocalDateTime.now().withDayOfMonth(1).minusDays(1)` (1st day of this month - 1 day = last day of last month). – Thomas Jan 12 '23 at 08:35
  • `Date` was always poorly designed. `Calendar` was a mostly failed attempt to make up for it and cumbersome to work with. `SimpleDateFormat` is notoriously troublesome. As @Thomas said, all of them were replaced by java.time, the modern Java date and time API nearly 9 years ago. So for your sanity move on. – Ole V.V. Jan 12 '23 at 09:23
  • Welcome to Stack Overflow. Please learn that you are supposed to search before asking here. It didn’t take me much to find something, for example [this: Java 8 – How to get last day / last working day of a month as LocalDate](https://www.javabrahman.com/java-8/java-8-how-to-get-last-day-last-working-day-of-a-month-as-localdate/). – Ole V.V. Jan 12 '23 at 09:33
  • 1
    `YearMonth.now().minusMonths( 1 ).atEndOfMonth()` per [my Answer](https://stackoverflow.com/a/25601193/642706) on other Question. – Basil Bourque Jan 12 '23 at 16:16

2 Answers2

3

You can get that date by using java.time

The idea is simple:

  • determine today
  • subtract a month
  • take the last day of the month

Here's a method:

public static LocalDate lastDayOfLastMonth() {
    /*
     * get "today", 
     * subtract a month and 
     * take the last day of the resulting month
     */
    return LocalDate.now()
                    .minusMonths(1)
                    .with(TemporalAdjusters.lastDayOfMonth());
}

You can use this method in a main and format the date as desired.

Example:

public static void main(String[] args) {
    // use the method to get the date
    LocalDate lastDayOfLastMonth = lastDayOfLastMonth();
    // define some formatters
    DateTimeFormatter dtf = DateTimeFormatter.ofPattern("MM/dd/uuuu");
    DateTimeFormatter anotherDtf = DateTimeFormatter.ofPattern(
                                        "EEEE, MMM dd uuuu", 
                                        Locale.ENGLISH
                                   );
    // print without a formatter (implicit use of toString())
    System.out.println(lastDayOfLastMonth);
    // print with different formatters
    System.out.println(lastDayOfLastMonth.format(dtf));
    System.out.println(lastDayOfLastMonth.format(anotherDtf));
}

Output:

2022-12-31
12/31/2022
Saturday, Dec 31 2022

(executed January 12 2023)

deHaar
  • 17,687
  • 10
  • 38
  • 51
2

Here is another approach, using the same classes:

    LocalDate today = LocalDate.now();
    LocalDate firstDayOfMonth = LocalDate.of(today.getYear(), today.getMonth(), 1);
    LocalDate lastDayOfLastMonth = firstDayOfMonth.minusDays(1);

    System.out.println(lastDayOfLastMonth); // prints on 2023-01-12: "2022-12-31"

As private method:

private LocalDate getLastDayOfLastMonth()
{
    LocalDate today = LocalDate.now();
    LocalDate firstDayOfMonth = LocalDate.of(today.getYear(), today.getMonth(), 1);
    LocalDate lastDayOfLastMonth = firstDayOfMonth.minusDays(1);
    return lastDayOfLastMonth;
}
actc
  • 672
  • 1
  • 9
  • 23
  • 1
    Thanks! this one works for me. I found out the the I run the bot I only initialize the date once now everytime the bot run I will initialize the date and make own method for it so that it will updated – Junry Buenavista Jan 12 '23 at 13:55