Last active
March 14, 2023 09:33
-
-
Save arturopala/9f76e24c5e56eb024ddf38c168dad4d1 to your computer and use it in GitHub Desktop.
Get an official GBP-PLN currency exchange rates on the pay-dates using NBP API. Runnable using scala-cli command.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//> using scala "2.13.8" | |
//> using lib "com.typesafe.play::play-ahc-ws-standalone:2.1.3" | |
//> using lib "com.typesafe.play::play-ws-standalone-json:2.1.3" | |
import java.time.LocalDate | |
import java.time.format.DateTimeFormatter | |
import akka.actor.ActorSystem | |
import play.api.libs.ws._ | |
import play.api.libs.ws.ahc._ | |
import play.api.libs.json._ | |
import play.api.libs.ws.JsonBodyReadables._ | |
import scala.concurrent.ExecutionContext.Implicits.global | |
import scala.concurrent.duration.Duration | |
import scala.concurrent.{Await, Future} | |
import com.fasterxml.jackson.core.JsonParseException | |
object GetRates extends App { | |
val year = args(0).toInt | |
println(s"NBP GBP-PLN exchange rates in year $year") | |
def getRate(currency: String, date: String): Future[BigDecimal] = { | |
val url = | |
s"http://api.nbp.pl/api/exchangerates/rates/a/$currency/$date/" | |
client | |
.url(url) | |
.get() | |
.map { response => | |
(response.body[JsValue] \ "rates" \ 0 \ "mid").as[BigDecimal] | |
} | |
.recover { case e: JsonParseException => | |
0 | |
} | |
} | |
implicit val system = ActorSystem("GetRates") | |
val client = StandaloneAhcWSClient() | |
val startDate = LocalDate.of(year, 1, 1) | |
val firstDayOfWeek = startDate.getDayOfWeek().getValue() | |
val firstFriday = | |
if (firstDayOfWeek > 5) startDate.plusDays(12 - firstDayOfWeek) | |
else startDate.plusDays(5 - firstDayOfWeek) | |
println( | |
s"First Friday of the year ${firstFriday.format(DateTimeFormatter.ISO_DATE)}" | |
) | |
val endDate = LocalDate.of(year, 12, 31) | |
val lastFriday = | |
endDate.minusDays((endDate.getDayOfWeek().getValue() + 2) % 7) | |
println( | |
s"Last Friday of the year ${lastFriday.format(DateTimeFormatter.ISO_DATE)}" | |
) | |
val numberOfWeeks = | |
(lastFriday.getDayOfYear() - firstFriday.getDayOfYear()) / 7 | |
println(s"Number of weeks $numberOfWeeks") | |
val rates = Await.result( | |
Future.sequence( | |
(0 until numberOfWeeks) | |
.scanLeft(firstFriday)((a, i) => a.plusDays(7)) | |
.map(date => | |
getRate("gbp", DateTimeFormatter.ISO_DATE.format(date)) | |
.map(rate => (date, rate)) | |
) | |
), | |
Duration.create("1m") | |
) | |
println("Found rates:") | |
rates.foreach { case (date, rate) => | |
println(s"${date.format(DateTimeFormatter.ISO_DATE)}\t$rate") | |
} | |
System.exit(0) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment