@s.d.engineering work your way through this that I just knocked up for you 
/* GetSunriseV1.ino Blynkified by Costas 28 May 2017
based on Sample Arduino Json Web Client original Copyright Benoit Blanchon 2014-2016
MIT License Arduino JSON library https://github.com/bblanchon/ArduinoJson
from https://stackoverflow.com/questions/39742067/arduino-json-parser-failing-to-parse-a-uri
*/
#define BLYNK_MAX_READBYTES 512 // can be around 360, needed for Webhook widget
#define DevicePin 2 // ESP LED, device is active LOW
#define BLYNK_PRINT Serial
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <ArduinoJson.h>
#include <TimeLib.h>
#include <WidgetRTC.h>
#include <Time.h>
WidgetRTC rtc;
BlynkTimer timer;
WiFiClient client;
char auth[] = "xxxx";
char ssid[] = "xxxx";
char pass[] = "xxxx";
char blynkserver[] = "blynk-cloud.com";
float timezoneAdj = 3; // needs to be float e.g -14.5
char ClockTimeSecs[9]; // Char Array to hold current time WITH seconds for display purposes
bool gotData = false; // for initial collection of sunrise / sunset times
char sunrise[12];
char sunset[12];
unsigned int Secstoday; // seconds from midnight to sunrise / sunset
unsigned int NowSeconds; // current seconds passed midnight
unsigned int sunriseSeconds = Secstoday; // secs since midnight to sunrise
unsigned int sunsetSeconds = Secstoday; // secs since midnight to sunset
bool deviceON = false; // true ON, false OFF default OFF for testing will go ON if "evening to dawn" and OFF if "daytime"
float latitude = 31.2345678; // TODO consider double not float
float longitude = 20.1234567; // TODO consider double not float
bool longEntered = true; // used for longitude and latitude entry in Terminal widget
unsigned int GetPressed = 0; // When V13 GET button is pressed use WiFiClient to get data not Webhook
unsigned int ApiPressed = 0; // When V17 API button is pressed use Webhok to get data not WiFiClient
long ProcessStartTime; // millis() counter for data processing time
bool isFirstConnect = true; // to fix RTC not syncing on reboot
const char* server = "api.sunrise-sunset.org"; // server's address
char resource[60]; // WAS /json?lat=25.044800&lng=43.977615&date=today";
int ilatitude = 35; // integer variable for latitude
int ilongitude = 33; // integer variable for longitude
int ilatrest = 44800; // should be 044800, decimal part of latitude
int ilongrest = 977615; // decimal part of longitude
const unsigned long HTTP_TIMEOUT = 3000; // max respone time from server
const size_t MAX_CONTENT_SIZE = 512; // max size of the HTTP response
void setup() {
//setSyncInterval(1); // try sync RTC every second until time is received
pinMode(DevicePin, OUTPUT); // define DevicePin as an output pin (test with onboard LED)
digitalWrite(DevicePin, HIGH); // test with device OFF at reboot
Serial.begin(115200);
Serial.println(F("\nStarted"));
Blynk.begin(auth, ssid, pass, blynkserver);
Blynk.syncVirtual(V19); // retrieve longitude value from server
Blynk.syncVirtual(V18); // retrieve latitude value from server
Serial.println(("Project started"));
rtc.begin(); // moved to BLYNK_CONNECTED following introduction of APP_CONNECTED function
timer.setInterval(1000L, checkTime); // update time every second
Blynk.virtualWrite(V20, "\n\n\n\n\nEnter your longitude\n");
// note the 0 hack for 25.044800 latitude
sprintf(resource, "/json?lat=%i.0%i&lng=%i.%i&date=today", ilatitude, ilatrest, ilongitude, ilongrest); // do in setup() and beyond
//Serial.println(resource);
}
void loop() {
if(Blynk.connected()){
Blynk.run();
//rtc.begin();
}
timer.run();
}
//
BLYNK_APP_CONNECTED() { // This is called when Smartphone App is opened
Serial.println(F("App Connected.")); // not currently working TODO
Blynk.notify("Blynk app just started OK");// send PUSH message each time Blynk app is started
}
BLYNK_APP_DISCONNECTED() { // This is called when Smartphone App is closed
Serial.println(F("App Disconnected.")); // not currently working TODO
Blynk.notify("Blynk app just stopped"); // send PUSH message each time Blynk app is stopped
}
//
/******************************************************************************************************/
/*
BLYNK_CONNECTED() { // see how it's used in TrackioT.ino sketch
if (isFirstConnect) {
setSyncInterval(1); // try sync RTC every second until time is received
Serial.println(F("RTC begins now"));
//isFirstConnect = false;
//rtc.begin(); // moved from setup() following introduction of APP_CONNECTED function
}
}
*/
/******************************************************************************************************/
void checkTime(){ // check for rollover of day and get data again
//Serial.println("107");
/*if(year() == 1970 && millis() > 24000 & millis() < 25000){ // start RTC 24 to 25s after ESP reboot
setSyncInterval(1); // try sync RTC every second until time is received from server
//rtc.begin();
Serial.println("Trying to sync RTC ........");
}*/
if(year() != 1970){ // time has updated from Blynk server
sprintf(ClockTimeSecs, "%02d:%02d:%02d", hour(), minute(), second()); // time with seconds
NowSeconds = (hour() * 3600) + (minute() * 60) + second(); // now seconds passed midnight
Blynk.virtualWrite(V12, ClockTimeSecs); // display clock time in app
if(!gotData){
ProcessStartTime = millis(); // record start time for data gathering
if(GetPressed){
GetPressed = 0; // clear the flag
getSunrise(); // call getSunrise only via GET button
}
else{
ApiPressed = 0; // clear the flag
clear4displays();
Blynk.virtualWrite(V18, String(latitude, 8) );
Blynk.virtualWrite(V19, String(longitude, 8));
Blynk.virtualWrite(V2, String(latitude, 8), String(longitude, 8) ); // TODO think String only gives 6dp AND reinstate the line
}
gotData = true;
}
//if((hour() == 12) && (minute() == 13) && (second() < 3) && (gotData)){ // test only
if((hour() == 0) && (minute() == 0) && (second() < 3) && (gotData)){ // day has rolled over, will only happen once a day
gotData = false; // used to call data again
}
if((NowSeconds >= sunriseSeconds) && (NowSeconds < sunsetSeconds) && (deviceON == true)){
digitalWrite(DevicePin, HIGH); // turn OFF device (active LOW)
deviceON = false;
Serial.print(F("Device turned OFF at "));
Serial.println(ClockTimeSecs);
Blynk.virtualWrite(V16, "Device turned OFF");
Blynk.virtualWrite(V20, "\nDevice turned OFF at " + String(ClockTimeSecs) + "\n");
}
if((NowSeconds >= sunsetSeconds) && (hour() < 24) && (deviceON == false)){ // i.e. before midnight check rollover?
digitalWrite(DevicePin, LOW); // turn ON device (active LOW)
deviceON = true;
Serial.print(F("Device turned ON at "));
Serial.println(ClockTimeSecs);
Blynk.virtualWrite(V16, "Device turned ON ");
Blynk.virtualWrite(V20, "\nDevice turned ON at " + String(ClockTimeSecs) + "\n");
}
if((NowSeconds < sunriseSeconds) && (deviceON == false)){ // i.e. before sunrise check rollover?
digitalWrite(DevicePin, LOW); // turn ON device (active LOW)
deviceON = true;
Serial.print(F("Device turned ON at "));
Serial.println(ClockTimeSecs);
Blynk.virtualWrite(V16, "Device turned ON ");
Blynk.virtualWrite(V20, "\nDevice turned ON at " + String(ClockTimeSecs) + "\n");
}
}
}
void displaySeconds(){
timefromArray(sunrise); // convert array to time
Serial.print(F("Sunrises "));
Serial.print(Secstoday);
Serial.println(F(" seconds after midnight today"));
Blynk.virtualWrite(V14, Secstoday);
sunriseSeconds = Secstoday;
timefromArray(sunset);
Serial.print(F("Sunsets "));
Serial.print(Secstoday);
Serial.println(F(" seconds after midnight today"));
Blynk.virtualWrite(V15, Secstoday);
sunsetSeconds = Secstoday;
}
void getSunrise(){
if (connect(server)) {
clear4displays();
if (sendRequest(server, resource) && skipResponseHeaders()) {
char response[MAX_CONTENT_SIZE];
readReponseContent(response, sizeof(response));
parseUserData(response);
}
disconnect();
}
}
void clear4displays(){
Blynk.virtualWrite(V10, "---------");
Blynk.virtualWrite(V11, "---------");
Blynk.virtualWrite(V14, "---------");
Blynk.virtualWrite(V15, "---------");
}
bool connect(const char* hostName) { // Open connection to the HTTP server
Serial.print(F("Connecting to "));
Serial.println(hostName);
bool ok = client.connect(hostName, 80);
Serial.print(ok ? "Connected to Sunrise server at " : "Connection Failed at ");
Serial.println(ClockTimeSecs);
return ok;
}
bool sendRequest(const char* host, const char* resource) { // Send the HTTP GET request to the server
//Serial.print("GET "); // TODO remove // if you want to see in Serial Monitor
//Serial.println(resource); // TODO remove // if you want to see in Serial Monitor
client.print("GET ");
client.print(resource);
//client.println(" HTTP/1.1");
client.println(" HTTP/1.0"); // needs to be 1.0 not 1.1
client.print("Host: ");
client.println(server);
client.println("Connection: close");
client.println();
return true;
}
bool skipResponseHeaders() { // Skip HTTP headers so that we are at the beginning of the response's body
// HTTP headers end with an empty line
char endOfHeaders[] = "\r\n\r\n";
client.setTimeout(HTTP_TIMEOUT);
bool ok = client.find(endOfHeaders);
if (!ok) {
Serial.println(F("No response or invalid response!"));
}
return ok;
}
void readReponseContent(char* content, size_t maxSize) { // Read the body of the response from the HTTP server
size_t length = client.readBytes(content, maxSize);
content[length] = 0;
Serial.println(content); // TODO remove // if you want to see in Serial Monitor
}
bool parseUserData(char* content) { // parse & print received data
// Compute optimal size of the JSON buffer according to what we need to parse.
// This is only required if you use StaticJsonBuffer.
const size_t BUFFER_SIZE =
JSON_OBJECT_SIZE(2) // the root object has 2 elements
+ JSON_OBJECT_SIZE(10); // the "result" object has 10 elements
// Allocate a temporary memory pool on the stack
StaticJsonBuffer<BUFFER_SIZE> jsonBuffer;
// If the memory pool is too big for the stack, use DynamicJsonBuffer jsonBuffer;
JsonObject& root = jsonBuffer.parseObject(content);
if (!root.success()) {
Serial.println("JSON parsing failed!");
return false;
}
// It's not mandatory to make a copy, you could just use the pointers
// Since, they are pointing inside the "content" buffer, make sure it's still in memory when you read the string
JsonObject& results = root["results"];
strcpy(sunrise, results["sunrise"]); // "2:32:19 AM"
strcpy(sunset, results["sunset"]); // "4:50:35 PM"
Serial.print(F("Sunrise = "));
Serial.print(sunrise);
Serial.println(F(" UTC, not local time"));
Serial.print(F("Sunset = "));
Serial.print(sunset);
Serial.println(F(" UTC, not local time"));
Blynk.virtualWrite(V10, sunrise); // TODO sometimes only showing 3dp with V13 (WiFi Client) button
Blynk.virtualWrite(V11, sunset); // TODO sometimes only showing 3dp with V13 (WiFi Client) button
displaySeconds(); // display seconds from midnight for sunrise / sunset
Serial.print(F("Processing time "));
Serial.print(millis() - ProcessStartTime);
Serial.println(F(" milliseconds"));
return true;
}
void disconnect() { // Close the connection with the HTTP server
Serial.println(F("Disconnected from Sunrise server"));
client.stop();
}
/********** function to convert api time into seconds since midnight with local timezone adjustment **********************/
int timefromArray(char* sunriseset){ // https://sunrise-sunset.org/api formats minutes and seconds with 2 digits (GOOD)
// https://api.sunrise-sunset.org/json?lat=25.044800&lng=43.977615&date=today
/* 28/5/17 is {"results":{"sunrise":"2:32:19 AM","sunset":"4:50:35 PM","solar_noon":"9:41:27 AM","day_length":"14:18:16",
"civil_twilight_begin":"2:03:22 AM","civil_twilight_end":"5:19:31 PM","nautical_twilight_begin":"1:27:45 AM",
"nautical_twilight_end":"5:55:08 PM","astronomical_twilight_begin":"12:48:56 AM","astronomical_twilight_end":"6:33:58 PM"},"status":"OK"}
Sunrise 19939 seconds local time
Sunset 71435 seconds local time
*/
unsigned int riseHours;
unsigned int riseMinutes;
unsigned int riseSeconds;
bool PMtime = false;
float timezoneAdj = 3.00; // needs to be float e.g -14.50 for minus 14 and a half hours behind UTC
char * p;
const char* lookfor = "AM";
p = strstr (sunriseset, lookfor); // search for first occurence of lookfor (AM) in sunrise
if((int) (p - sunriseset) > 0){ // must be this way as p is a pointer
PMtime = false;
}
else{
PMtime = true;
}
riseHours = atoi(&sunriseset[0]);
unsigned int x = 0;
if(String(strlen(sunriseset))== "10"){ // value is a string not an int
x = 1;
}
riseMinutes = atoi(&sunriseset[3 - x]);
riseSeconds = atoi(&sunriseset[6 - x]);
Secstoday = (riseHours * 3600) + (riseMinutes * 60) + riseSeconds;
if(PMtime){ // if PM, add 12 hours x 60 minutes x 60 seconds = 43200 seconds
Secstoday = Secstoday + 43200;
}
Secstoday = Secstoday + (timezoneAdj * 3600); // timezone adjustment
return Secstoday;
}
/************************** Blynk widgets *************************************************************/
BLYNK_WRITE(V2){ // Webhook pin for sunrise api
String webhookdata = param.asStr();
Serial.println(webhookdata);
char apiCall[webhookdata.length() + 1];
webhookdata.toCharArray(apiCall, (webhookdata.length() + 1)); // convert String to Char array
webhookdata = "";
parseUserData(apiCall);
gotData = true;
}
BLYNK_WRITE(V13){ // button to call getSunrise() via WiFi Client;
int LocalGetPressed = param.asInt();
if(LocalGetPressed){
GetPressed = LocalGetPressed; // global variable
resource[0] = (char)0; // start to create a new resource for client call by clearing existing char array
ilatitude = int(latitude + 0.0); // e.g. 25.1234567 becomes 25 rounding not required
int tmplat = latitude * 10000000L; // e.g. 351234567
//Serial.println(tmplat);
int tmplatitude = ilatitude * 10000000L; // e.g. 250000000
ilatrest = tmplat - tmplatitude; // e.g. 1234567
//Serial.println(ilatrest);
// 0 hack follows e.g. for 23.044800 latitude etc
if(ilatrest < 1000000){ // e.g 0123456 only 6 digits not 7 so pad with 0
sprintf(resource, "/json?lat=%i.0%i&lng=", ilatitude, ilatrest); // padded decimals with 0 for latitude
}
else{
sprintf(resource, "/json?lat=%i.%i&lng=", ilatitude, ilatrest); // no decimal padding required for latitude
}
ilongitude = int(longitude + 0.0); // e.g. 25.1234567 becomes 25 rounding not required
int tmplong = longitude * 10000000L; // e.g. 351234567
//Serial.println(tmplong);
int tmplongitude = ilongitude * 10000000L; // e.g. 350000000
ilongrest = tmplong - tmplongitude; // e.g. 1234567
//Serial.println(ilongrest);
// 0 hack follows e.g. for 23.044800 longitude etc
if(ilongrest < 1000000){ // e.g 0123456 only 6 digits not 7 so pad with 0
sprintf(resource, "%s%i.0%i&date=today", resource, ilongitude, ilongrest); // padded decimals with 0 for longitude
}
else{
sprintf(resource, "%s%i.%i&date=today", resource, ilongitude, ilongrest); // no decimal padding required for longitude
}
Serial.println(resource); // 0 padding adds a 7th decimal place but it's only a few mm
gotData = false; // reset flag
checkTime(); // this will call getSunrise();
}
}
BLYNK_WRITE(V17){ // button to call Webhook API
int LocalApiPressed = param.asInt();
if(LocalApiPressed){
ApiPressed = LocalApiPressed; // global variable
gotData = false; // reset flag
}
}
BLYNK_WRITE(V18){ // display widget for latitude, sync on ESP restart
latitude = param.asFloat();
//Serial.println(latitude, 7);
}
BLYNK_WRITE(V19){ // display widget for longitude, sync on ESP restart
longitude = param.asFloat();
//Serial.println(longitude, 7);
}
BLYNK_WRITE(V20){ // Terminal widget to enter longitude and latitude
String terminalString = param.asStr();
if(longEntered == true){
Blynk.virtualWrite(V20, "\n\n\n\n\nEnter your latitude\n");
longitude = terminalString.toFloat(); // convert String to float
Serial.println(longitude, 7);
Blynk.virtualWrite(V19, String(longitude, 8));
longEntered = false;
}
else{
Blynk.virtualWrite(V20, "\n\n\n\n\nEnter your longitude\n");
latitude = terminalString.toFloat(); // convert String to float
Serial.println(latitude, 7);
Blynk.virtualWrite(V18, String(latitude, 8));
longEntered = true;
}
}